最有效的方法从列表中删除重复项 [英] Most efficient way to remove duplicates from a List

查看:251
本文介绍了最有效的方法从列表中删除重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,我有重复的值的列表,我想删除重复的。

 列表< INT> myList中=新名单< INT>(Enumerable.Range(0,10000));
myList.Add(1);
myList.Add(2);
myList.Add(2);
myList.Add(3);

我发现3的方法来解决这个问题:

 列表< INT>结果1 =新的HashSet< INT>(myList中).ToList(); // 3700蜱
清单< INT>结果2 = myList.Distinct()了ToList()。 // 4700蜱
清单< INT> Result3 = myList.GroupBy(X =&X的催化剂)。选择(GRP = GT; grp.First())。了ToList(); // 18800蜱

在大多数的答案在这里的话,鲜明办法显示为正确的,然而HashSet的始终是更快!

我的问题:有什么我必须要知道,当我使用 HashSet的的做法,是有另一种更有效的方式。

更新指pinturic的评论:

 列表< INT> Result4 =新的SortedSet< INT>(myList中).ToList(); // 18000蜱


解决方案

有这两个方法之间有很大的区别:

 列表< INT>结果1 =新的HashSet< INT>(myList中).ToList(); // 3700蜱
清单< INT>结果2 = myList.Distinct()了ToList()。 // 4700蜱

第一个可以(可能会)改变返回名单,LT的元素的顺序;> 结果1 元素不会在 myList中的那些相同的顺序。第二保持原有顺序。

有可能没有比第一个更快的方法。

有可能是没有更正确(为正确的一定的定义,根据排序)比第二。

(第三个是类似于第二个,仅慢)

只是出于好奇,在鲜明的()是:

  //参考源http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,712
公共静态的IEnumerable< TSource>不同的< TSource>(这个IEnumerable的< TSource>源){
    如果(来源== NULL)抛出Error.ArgumentNull(源);
    返回DistinctIterator< TSource>(源,NULL);
}//参考源http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,722
静态的IEnumerable< TSource> DistinctIterator< TSource>(IEnumerable的< TSource>源的IEqualityComparer< TSource>比较器){
    SET< TSource>设置=新集< TSource>(比较器);
    的foreach(源TSource元素)
        如果(set.Add(元素))收益回报元素;
}

所以,最后的鲜明的()只需使用一个内部实现的的HashSet<> (被称为设置<方式> )来检查项目的独特性

有关完整起见,我将添加一个链接到这个问题是否C#鲜明的()方法保留序列的原始顺序不变?

Let's say I have a List with duplicate values and I want to remove the duplicates.

List<int> myList = new List<int>(Enumerable.Range(0, 10000));
myList.Add(1);
myList.Add(2);
myList.Add(2);
myList.Add(3);

I have found 3 approaches to solve this:

List<int> Result1 = new HashSet<int>(myList).ToList(); //3700 ticks
List<int> Result2 = myList.Distinct().ToList(); //4700 ticks
List<int> Result3 = myList.GroupBy(x => x).Select(grp => grp.First()).ToList(); //18800 ticks

In most answers here on SO, the Distinct approach is shown as the "correct one", yet the HashSet is always faster!

My question: is there anything I have to be aware of when I use the HashSet approach and is there another more efficient way?

Update referring to pinturic's comment:

List<int> Result4 = new SortedSet<int>(myList).ToList(); //18000 ticks

解决方案

There is a big difference between these two approaches:

List<int> Result1 = new HashSet<int>(myList).ToList(); //3700 ticks
List<int> Result2 = myList.Distinct().ToList(); //4700 ticks

The first one can (will probably) change the order of the elements of the returned List<>: Result1 elements won't be in the same order of myList's ones. The second maintains the original ordering.

There is probably no faster way than the first one.

There is probably no "more correct" (for a certain definition of "correct" based on ordering) than the second one.

(the third one is similar to the second one, only slower)

Just out of curiousity, the Distinct() is:

// Reference source http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,712
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    return DistinctIterator<TSource>(source, null);
}

// Reference source http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,722
static IEnumerable<TSource> DistinctIterator<TSource>(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer) {
    Set<TSource> set = new Set<TSource>(comparer);
    foreach (TSource element in source)
        if (set.Add(element)) yield return element;
}

So in the end the Distinct() simply uses an internal implementation of an HashSet<> (called Set<>) to check for the uniqueness of items.

For completeness sake, I'll add a link to the question Does C# Distinct() method keep original ordering of sequence intact?

这篇关于最有效的方法从列表中删除重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆