C#从List <List <int >>中删除重复项

mar*_*s84 14 c# list duplicates removeall

我无法想出最有效的算法来删除重复项List<List<int>>,例如(我知道这看起来像一个列表int[],但只是为了视觉目的这样做:

my_list[0]= {1, 2, 3};
my_list[1]= {1, 2, 3};
my_list[2]= {9, 10, 11};
my_list[3]= {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

所以输出就是

new_list[0]= {1, 2, 3};
new_list[1]= {9, 10, 11};
Run Code Online (Sandbox Code Playgroud)

如果您有任何想法,请告诉我.我真的很感激.

cuo*_*gle 12

建立定制EqualityComparer<List<int>>:

public class CusComparer : IEqualityComparer<List<int>>
{
    public bool Equals(List<int> x, List<int> y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(List<int> obj)
    {
        int hashCode = 0;

        for (var index = 0; index < obj.Count; index++)
        {
            hashCode ^= new {Index = index, Item = obj[index]}.GetHashCode();
        }

        return hashCode;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用Distinct with custom comparer方法获得结果:

var result = my_list.Distinct(new CusComparer());
Run Code Online (Sandbox Code Playgroud)

编辑:

将索引包含在方法中GetHashCode以确保不同的订单不相​​等

  • 那个哈希码会导致很多冲突 - 例如``a,a}`会碰到任何'a`,`{a,b}`会与`{b,a}`发生碰撞,任何排列都会发生...... (虽然你可能会碰撞碰撞,但在这种情况下,回答很好!) (3认同)

Len*_*rri 10

这个简单的程序可以满足您的需求:

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

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            List<List<int>> lists = new List<List<int>>();

            lists.Add(new List<int> { 1, 2, 3 });
            lists.Add(new List<int> { 1, 2, 3 });
            lists.Add(new List<int> { 9, 10, 11 });
            lists.Add(new List<int> { 1, 2, 3 });

            var distinct = lists.Select(x => new HashSet<int>(x))
                    .Distinct(HashSet<int>.CreateSetComparer());

            foreach (var list in distinct)
            {
                foreach (var v in list)
                {
                    Console.Write(v + " ");
                }

                Console.WriteLine();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案,因为它充分利用Linq来简化问题. (2认同)

L.B*_*L.B 9

    var finalList = lists.GroupBy(x => String.Join(",", x))
                         .Select(x => x.First().ToList())
                         .ToList();
Run Code Online (Sandbox Code Playgroud)


Tim*_* S. 6

您可以使用Distinct带有比较器的LINQ 重载.比较器应该查看列表是否相等.请注意,默认等于列表的操作将不会执行您真正想要的操作,因此比较器将需要为您循环遍历每个操作.这是一个这样的比较器的例子:

public class SequenceComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    IEqualityComparer<T> itemComparer;
    public SequenceComparer()
    {
        this.itemComparer = EqualityComparer<T>.Default;
    }

    public SequenceComparer(IEqualityComparer<T> itemComparer)
    {
        this.itemComparer = itemComparer;
    }

    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        if (object.Equals(x, y))
            return true;
        if (x == null || y == null)
            return false;
        return x.SequenceEqual(y, itemComparer);
    }

    public int GetHashCode(IEnumerable<T> obj)
    {
        if (obj == null)
            return -1;
        int i = 0;
        return obj.Aggregate(0, (x, y) => x ^ new { Index = i++, ItemHash = itemComparer.GetHashCode(y) }.GetHashCode());
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:我想到了使用匿名类型从Cuong Le的答案中获得更好的哈希值,并且我对它进行了LINQ-ified并让它在我的课堂上运行.