我应该如何快速比较两个通用列表,以及检查它们是否相同的内容?

发布于 2025-02-03 09:53:58 字数 628 浏览 4 评论 0原文

//在这里,我有一个列表

List<List<T>> SelectionList = new List<List<T>>();

//我当前的代码比较列表

    for(int i = 0; i < SelectionList.Count; i++)
    {
        for(int j = 0; j < SelectionList.Count; j++)
        {
            if (SelectionList[i].Equals(SelectionList[j]))
            {
                SelectionList.Remove(SelectionList[j]);
            }
        }
    }

// 注意:上面的代码据称有效,以防万一如果两个列表的内容均已排序,即它们处于相同的索引,但是在我的列表中,它们可能相同,但列表内容被调整。在这种情况下,它无法识别。

//基本上,我需要删除列表列表中同一列表的任何重复;

//Here I have a List of Lists

List<List<T>> SelectionList = new List<List<T>>();

//My current code to compare lists

    for(int i = 0; i < SelectionList.Count; i++)
    {
        for(int j = 0; j < SelectionList.Count; j++)
        {
            if (SelectionList[i].Equals(SelectionList[j]))
            {
                SelectionList.Remove(SelectionList[j]);
            }
        }
    }

//Note: The above code supposedly works, in cases where the contents of both the lists are ordered ie., they are in same index, but in my lists they might be same but list contents are shuffled. in this case it fails to identify.

//Basically I need to remove any repetitions of same list in my list of lists;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

太阳哥哥 2025-02-10 09:53:58

if(and仅考虑)以下内容是正确的:

  • 您的单个列表不包含
  • 列表元素的类型t的类型 iComparable and gethashcode(gethashcode()< /code>正确地

,您可以删除与早期列表相匹配的每个

for (int i = lists.Count - 1; i > 0; i--)
{
    for (int j = i - 1; j >= 0; j--)
    {
        if (!lists[i].Except(lists[j]).Any())
        {
            lists.RemoveAt(i);
            break;
        }
    }
}

列表:!lists [i] .except(lists [j])。任何()

让我们将其分解为:

lists [i] .except(lists [j]): - 这会产生lists [i]的所有元素的顺序列表[J],无论订单如何。

因此,如果列表中的所有项目[j]也都在列表中[J]中,则会产生一个空序列;否则,它将产生非空序列。

.yany()()将返回非空序列的true ,而对于空序列的false

因此lists [i] .except(lists [j])。任何()将返回false如果项目在每个列表中相同,true true 代码>如果它们有所不同。

这与我们想要的lists.removeat()的相反,因此我们只是否定结果,提供最终代码!lists [i] .except(lists [j])。任何()

编译控制台应用程序:

using System;
using System.Collections.Generic;
using System.Linq;

static class Program
{
    static void Main()
    {
        var lists = new List<List<int>>
        {
            new() {1, 2, 3, 4, 5}, // [0]
            new() {2, 3, 4, 5, 6}, // [1]
            new() {3, 4, 5, 6, 7}, // [2]
            new() {5, 4, 3, 2, 1}, // [3] Dupe of [0]
            new() {4, 5, 6, 7, 8}, // [4]
            new() {6, 5, 4, 3, 2}, // [5] Dupe of [1]
            new() {5, 6, 7, 8, 9}, // [6] 
            new() {3, 4, 5, 2, 1}, // [7] Dupe of [0]
            new() {6, 7, 8, 9, 0}  // [8]
        };

        for (int i = lists.Count - 1; i > 0; i--)
        {
            for (int j = i - 1; j >= 0; j--)
            {
                if (!lists[i].Except(lists[j]).Any())
                {
                    lists.RemoveAt(i);
                    break;
                }
            }
        }

        for (int i = 0; i < lists.Count; ++i)
        {
            Console.WriteLine(string.Join(", ", lists[i]));
        }
    }

在dotnetfiddle上尝试: https://dotnetfiddle.net/nwnocp

If (and only if) the following is true:

  • Your individual lists do not contain any duplicates
  • The type T of your list elements implements IComparable and GetHashCode() correctly

Then you can remove each list that matches an earlier list like so (note that you must traverse the list backwards when removing items from the end of it otherwise the loop indices could go out of range):

for (int i = lists.Count - 1; i > 0; i--)
{
    for (int j = i - 1; j >= 0; j--)
    {
        if (!lists[i].Except(lists[j]).Any())
        {
            lists.RemoveAt(i);
            break;
        }
    }
}

The important line here is: !lists[i].Except(lists[j]).Any().

Let's break it down:

lists[i].Except(lists[j]): - This produces a sequence of all the elements of lists[i] that are NOT in lists[j], regardless of order.

Thus if all of the items in lists[j] are also in lists[j], this will produce an empty sequence; otherwise, it will produce a non-empty sequence.

The .Any() will return true for a non-empty sequence, and false for an empty sequence.

So lists[i].Except(lists[j]).Any() will return false if the items are the same in each list and true if they differ.

This is the opposite of what we want for the lists.RemoveAt() so we just negate the result, giving the final code !lists[i].Except(lists[j]).Any().

Compilable console app:

using System;
using System.Collections.Generic;
using System.Linq;

static class Program
{
    static void Main()
    {
        var lists = new List<List<int>>
        {
            new() {1, 2, 3, 4, 5}, // [0]
            new() {2, 3, 4, 5, 6}, // [1]
            new() {3, 4, 5, 6, 7}, // [2]
            new() {5, 4, 3, 2, 1}, // [3] Dupe of [0]
            new() {4, 5, 6, 7, 8}, // [4]
            new() {6, 5, 4, 3, 2}, // [5] Dupe of [1]
            new() {5, 6, 7, 8, 9}, // [6] 
            new() {3, 4, 5, 2, 1}, // [7] Dupe of [0]
            new() {6, 7, 8, 9, 0}  // [8]
        };

        for (int i = lists.Count - 1; i > 0; i--)
        {
            for (int j = i - 1; j >= 0; j--)
            {
                if (!lists[i].Except(lists[j]).Any())
                {
                    lists.RemoveAt(i);
                    break;
                }
            }
        }

        for (int i = 0; i < lists.Count; ++i)
        {
            Console.WriteLine(string.Join(", ", lists[i]));
        }
    }

Try it on DotNetFiddle: https://dotnetfiddle.net/nWnOcP

浊酒尽余欢 2025-02-10 09:53:58

如果对于每个列表,每个可能的值最多出现在列表中一次,则可以使用dictionary&lt; t,int&gt;存储元素出现的频率。然后,您执行以下步骤:

  1. 迭代列表,对于每个列表,请执行以下操作:对于每个列表元素k,检查字典是否包含它作为键。如果没有,则将键k添加为value 1 到您的字典中。如果是这样,请通过1来递增键k的值。
  2. 迭代字典的元素,并检查所有值均为2(如果您有两个列表)或n(如果您有n列表)。

If, for each list, each possible value appears at most once in the list, you could use a Dictionary<T,int> to store how often an element appears. Then you perform the following steps:

  1. Iterate over the lists, and, for each list, do the following: For each list element k, check if the dictionary contains it as a key. If it does not, then add key k with value 1 to your dictionary. If it does, then increment the value for key k by 1.
  2. Iterate over the dictionary's elements and check that all values are 2 (if you have two lists) or n (if you have n lists).
记忆里有你的影子 2025-02-10 09:53:58

正如您所说,您的方式是不正确的,请尝试以下操作:

您应该在列表上迭代以下程序;

private bool Compare(List<T> List1,List<T> List2)
{
   var infirstNotSecond = list1.Except(list2).ToList();
   var insecondNotFirst = list2.Except(list1).ToList();
   return !infirstNotSecond.Any() && !insecondNotFirst.Any();
}

Your way is not correct, as you said, try this:

you should iterate the following procedure over your list-Of-Lists;

private bool Compare(List<T> List1,List<T> List2)
{
   var infirstNotSecond = list1.Except(list2).ToList();
   var insecondNotFirst = list2.Except(list1).ToList();
   return !infirstNotSecond.Any() && !insecondNotFirst.Any();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文