簡體   English   中英

從List中刪除重復項的最有效方法

[英]Most efficient way to remove duplicates from a List

假設我有一個包含重復值的List,我想刪除重復項。

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

// adding a few duplicates here
myList.Add(1); 
myList.Add(2);
myList.Add(3);

我找到了3種方法來解決這個問題:

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
//referring to pinturic's comment:
List<int> result4 = new SortedSet<int>(myList).ToList(); //18000 ticks

在SO的大多數答案中, Distinct方法顯示為“正確的”,但HashSet總是更快!

我的問題:當我使用HashSet方法時,有什么我必須要注意的,還有另一種更有效的方法嗎?

這兩種方法有很大的不同:

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

第一個可以(可能)更改返回的List<>元素的順序: Result1元素與myList的元素的順序不同。 第二個保持原始排序。

可能沒有比第一個更快的方式。

對於第二個,可能沒有“更正確”(對於基於排序的“正確”的某種定義)。

(第三個類似於第二個,只是更慢)

出於好奇, Distinct()是:

// 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;
}

所以最后, Distinct()只使用HashSet<> (稱為Set<> )的內部實現來檢查項的唯一性。

為了完整起見,我將添加一個問題的鏈接C#Distinct()方法保持序列的原始排序完整嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM