假設我正在使用LINQ數組.Distinct()
方法。 結果無序。LINQ .distinct方法如何排序?
那麼,如果你知道用於產生結果的邏輯,那麼一切都是「有序的」。
我的問題是關於結果集。結果數組是否處於「第一個不同」順序或可能是「最後一個不同」順序?
我可以不指望任何訂單嗎?
這是舊的「刪除重複的字符串」的問題,但我正在研究LINQ解決方案。
假設我正在使用LINQ數組.Distinct()
方法。 結果無序。LINQ .distinct方法如何排序?
那麼,如果你知道用於產生結果的邏輯,那麼一切都是「有序的」。
我的問題是關於結果集。結果數組是否處於「第一個不同」順序或可能是「最後一個不同」順序?
我可以不指望任何訂單嗎?
這是舊的「刪除重複的字符串」的問題,但我正在研究LINQ解決方案。
假設你的意思是LINQ to Objects,它基本上保留了它到目前爲止返回的所有結果的集合,並且如果它之前沒有被放棄,只會產生「當前」項目。所以結果是按原始順序排除重複項。這樣的事情(除了錯誤檢查等):
public static IEnumerable<T> Distinct<T>(this IEnumerable<T> source)
{
HashSet<T> set = new HashSet<T>();
foreach (T item in source)
{
if (set.Add(item))
{
// New item, so yield it
yield return item;
}
}
}
這並不是保證 - 但我不能想象任何更明智的實施。這允許Distinct()
儘可能地遲緩 - 儘可能快地返回數據,並且只有最少量的數據被緩衝。
依靠這將是一個壞主意,但它可以有助於知道當前實現(顯然)如何工作。特別是,您可以很容易地觀察到,它在數據從Distinct
收到數據之前,通過創建一個記錄它產生要被Distinct
消耗的數據的日誌時,在耗盡原始序列之前返回數據,並且還記錄您的。
據我所知,Distinct方法並沒有正式保證訂單,儘管實際上LINQ to Objects實現以它們首次出現在源枚舉中的順序返回組。
如果你使用LINQ to SQL,那麼它由數據庫決定它希望返回結果的順序,然後你不應該依賴這個順序,即使從一個調用到下一個調用是一致的。
你永遠不能指望任何順序。 LINQ完全可以使用哈希表來實現這一點(事實上,我相信它是在.NET 4中以這種方式實現的)。
猜測它使用一個散列表來產生一組不同的密鑰,並按散列順序產生輸出。
的docs說:
「的結果序列是無序的。」
我知道這一點。我的觀點是,秩序是「隨機」的概念實際上並不成立,除非這種方法對我來說完全是陌生的。 – Matthew 2010-11-05 20:52:23
@matthew:好的,但你問:「我不能依靠任何訂單?「由於文檔清楚地表明結果是無序的,所以你不能依靠任何順序,如果今天按照某個順序,下一個.NET錯誤修正可能會改變,因爲沒有順序保證 – 2010-11-05 20:54:12
@matthew:檢查Jon的答案,最好的順序是數據進來的順序,但正如每個人一直在說的那樣,並且按照文檔,不能保證任何特定的順序,如果您需要訂單,請將OrderBy添加到Linq,例如'var result = sourceItems.Distinct()。OrderBy(item => item.ValueToOrderOn)' – Will 2010-11-05 21:04:38
您也可以將您自己的擴展方法(例如DistinctOrdered)添加到Jon提供的實現中。這樣,無論.NET Framework的版本如何,您都將始終使用已定義的順序進行實現。 –
Karsten
2015-11-04 19:37:56
添加到[Jon Skeet Facts](http://meta.stackexchange.com/questions/9134/jon-skeet-facts) - [.NET Reference Source](https://referencesource.microsoft.com/# System.Core/System/Linq/Enumerable.cs,4ab583c7d8e84d6d)是基於Jon Skeet的答案 – Slai 2017-01-17 17:19:31