List.Distinct()是否适用于List <list <string>&gt;的列表类型?</list <string>

时间:2013-08-13 07:17:19

标签: c# list

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个元素。可能的原因是什么?

4 个答案:

答案 0 :(得分:6)

这是因为List<T>没有实现EqualsGetHashCode,因此正在执行标准参考比较。它返回false,因为你有两个单独的列表。

您可以编写自己的IEqualityComparer<List<string>>实现,并将其作为Distinct方法参数提供。在比较器中,您可以使用Enumerable.SequenceEqual)方法检查列表是否具有相同的内容。

答案 1 :(得分:2)

根据您的情况,您必须构建自定义比较器以实现接口IEqualityComparer<List<string>>,并使用SequenceEqualEqual方法中进行比较:

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();

答案 2 :(得分:1)

List使用的比较基于参考比较。由于2个列表是不同的实例,因此它们不同,并且不同的认为它们是不同的。

答案 3 :(得分:1)

如果您想要不同的值,可以使用.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));