List.Distinct() 可以应用于 List> 的列表类型吗?
本文关键字:List 列表 类型 Distinct String 应用于 | 更新日期: 2023-09-27 18:27:22
List<List<String>> ls = new List<List<String>>();
List<String> l1 = new List<String>();
l1.Add("Peter");
l1.Add("123");
ls.Add(l1);
List<String> l2 = new List<String>();
l2.Add("Peter");
l2.Add("123");
ls.Add(l2);
ls = ls.Distinct().ToList();
我想ls中只有一个元素,但实际上仍然有2个元素。可能的原因是什么?
这是因为List<T>
没有Equals
并且GetHashCode
实现的,因此正在执行标准引用比较。它返回 false,因为你有两个单独的列表。
您可以编写自己的IEqualityComparer<List<string>>
实现,并将其作为方法参数提供Distinct
。在比较器中,您可以使用 Enumerable.SequenceEqual
( 方法来检查列表是否具有相同的内容。
对于您的情况,您必须构建自定义比较器来实现接口IEqualityComparer<List<string>>
,并使用SequenceEqual
在Equal
方法中进行比较:
public class CustomComparer : IEqualityComparer<List<string>>
{
public bool Equals(List<string> x, List<string> y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(List<string> obj)
{
int hashCode = 0;
foreach (string str in obj)
{
hashCode ^= str.GetHashCode();
}
return hashCode;
}
}
然后:
ls = ls.Distinct(new CustomComparer()).ToList();
使用GroupBy
区分的另一种棘手方法:
ls = ls.GroupBy(x => string.Join("", x))
.Select(g => g.First())
.ToList();
List 使用的比较基于引用比较。由于这两个列表是不同的实例,因此它们并不相同,并且不同认为它们是不同的。
如果需要非重复值,可以使用.SelectMany()
选择父列表内每个列表中的字符串:
var list = new List<List<String>>();
var list1 = new List<String>();
list1.Add("Peter");
list1.Add("123");
list.Add(list1);
var list2 = new List<String>();
list2.Add("Peter");
list2.Add("123");
list.Add(list2);
var distinct = list.SelectMany(x => x).Distinct().ToList();
distinct.ForEach(x => Console.WriteLine(x));