2016-09-07 20 views
0

當我在下圖中應用DISTINCT.ToList()時,將從結果列表中刪除哪些項目? 是否將第一個條目(即第一個添加到列表中)重複保存在要返回的新列表中?如果沒有,是否有辦法讓DISTINCT.ToList()保留新列表中的重複項中的第一個條目被返回?在使用List.Distinct()時返回項目在結果列表中的順序

Dim values As List(Of Integer) = New List(Of Integer) 
    values.Add(1) 
    values.Add(5) 
    values.Add(2) 
    values.Add(3) 
    values.Add(2) 
    values.Add(3) 
    values.Add(4) 
    values.Add(2) 
    values.Add(2) 
    values.Add(3) 
    values.Add(3) 
    values.Add(3) 

    Dim items As List(Of Integer) = values.Distinct().ToList 

    ' Display result. 
    For Each i As Integer In items 
     Console.WriteLine(i) 
    Next 

Expected output: 
1 
5 
2 
3 
4 

MSDN頁面上顯示 「鮮明(中TSource)(IEnumerable的(中TSource))方法返回一個不包含重複值無序序列」。有沒有辦法解決這個問題?

+2

實際上,沒有項目將從列表中刪除,包含不同項目的新列表將被返回。 – hellowstone

+1

您可以隨時添加一個擴展方法,你自己,做爲了它:'公共靜態IOrderedEnumerable OrderedDistinct(這IEnumerable的數據){返回data.Distinct()排序依據(X => X)。 }' – Maarten

+0

用'Distinct'操作返回的列表僅包含第一個發生的原始項目,並且沒有排序。所以你必須期望在你的例子中你的預期輸出。 – hellowstone

回答

4

不,你不能使用Distinct來解決這個問題。正如它所發生的那樣,它的工作原理與您的預期完全相同,但文檔明確指出它不能保證。因此,在未來的框架版本中實現可能會發生變化,因此您不能依賴它。該方法編寫簡單。事實上,你甚至可以複製the framework implementation

再次 - 它目前的工作方式如你所願,但不保證將來會這樣做。

另一方面,我非常有信心這個實現永遠不會改變,因爲我無法想象更高效的實現存在。

下面是完整的實現(抱歉,這是C#和VB.NET不)

public static class MyEnumerable 
{ 
    public static IEnumerable<T> Distinct<T>(this IEnumerable<T> source) 
    { 
     if (source == null) 
     { 
      throw new ArgumentNullException(nameof(source)); 
     } 

     var items = new HashSet<T>(); 

     foreach (T item in source) 
     { 
      if (items.Add(item)) 
      { 
       yield return item; 
      } 
     } 
    } 
} 
1

不,你不能左右它獲得與該框架提供的標準方法。你可以像Stilgar建議的那樣自己編寫代碼來繞過它。

隨着提供的指數選擇的第一個項目的例子在技術上是不相關的,你將無法知道,如果它是第一個或第100出現在自詮釋名單是結構。

但這說我猜你正在使用自定義對象。在這種情況下,您的訂單來自某種排序。在這種情況下,我建議你,而不是你的OrderBy<>語句中使用GroupBy<>,然後爲每個組訂單中的項目,並做一個First<>

Group by和Distinct非常接近。不同的可以被一個組取代,然後每個組首先取代。事實上,它比真正的實現要慢得多,但是這裏的目標是解釋如果你最終需要的不僅僅是第一項,你如何使用它來定製輸出。

相關問題