2
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

4 回答 4

6

那是因为List<T>没有EqualsGetHashCode实施,所以正在执行标准参考比较。它返回 false,因为您有两个单独的列表。

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

于 2013-08-13T07:18:54.383 回答
2

对于您的情况,您必须构建自定义比较器来实现接口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();
于 2013-08-13T07:22:00.677 回答
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));
于 2013-08-13T07:25:58.080 回答
1

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

于 2013-08-13T07:19:47.063 回答