[英]How shall I Quickly compare two generic lists and it's contents for checking if they are identical?
//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; //基本上我需要删除列表列表中相同列表的任何重复;
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.如果对于每个列表,每个可能的值在列表中最多出现一次,则可以使用Dictionary<T,int>
来存储元素出现的频率。 Then you perform the following steps:然后执行以下步骤:
k
, check if the dictionary contains it as a key.遍历列表,对于每个列表,执行以下操作: 对于每个列表元素k
,检查字典是否包含它作为键。 If it does not, then add key k
with value 1
to your dictionary.如果没有,则将值为1
的键k
添加到您的字典中。 If it does, then increment the value for key k
by 1
.如果是,则将键k
的值增加1
。2
(if you have two lists) or n
(if you have n
lists).遍历字典的元素并检查所有值是否为2
(如果您有两个列表)或n
(如果您有n
列表)。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();
}
If (and only if) the following is true:如果(且仅当)以下情况为真:
T
of your list elements implements IComparable
and GetHashCode()
correctly列表元素的类型T
正确实现IComparable
和GetHashCode()
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()
.这里重要的一行是: !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. lists[i].Except(lists[j])
: - 这会产生 list[i lists[i]
中不在 lists[ lists[j]
] 中的所有元素的序列,无论顺序如何。
Thus if all of the items in lists[j]
are also in lists[j]
, this will produce an empty sequence;因此,如果lists[j]
中的所有项目也都在lists[j]
中,这将产生一个空序列; otherwise, it will produce a non-empty sequence.否则,它将产生一个非空序列。
The .Any()
will return true
for a non-empty sequence, and false
for an empty sequence. .Any()
将为非空序列返回true
,为空序列返回false
。
So lists[i].Except(lists[j]).Any()
will return false
if the items are the same in each list and true
if they differ.因此, lists[i].Except(lists[j]).Any()
如果每个列表中的项目相同,则返回false
,如果它们不同,则返回true
。
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()
.这与我们想要的lists.RemoveAt()
相反,所以我们只是否定结果,给出最终代码!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在 DotNetFiddle 上试试: https ://dotnetfiddle.net/nWnOcP
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.