2011-05-20 64 views

回答

2

GroupBy,如果明智地做到了,只能在一次轉發中使用。基本實現(而不是他們)會是這樣媲美到:通過關鍵

var data = new Dictionary<TKey, List<TValue>>(comparer); 
foreach(var item in source) { 
    var key = keySelector(item); 
    List<TValue> list; 
    if(!data.TryGetValue(key, out list)) 
    { 
     data.Add(key, list = new List<TValue>()); 
    } 
    list.Add(itemSelector(item)); 
} 

,基本上組,爲每個唯一的密鑰生成一個列表,包含值。

可能做比較最後看到的鍵(幫助排序的數據),但...你需要知道它是否值得。

2

就讓我們看看超載

IEnumerable<IGrouping<TKey, TSource>> Enumerable.GroupBy<TSource, TKey>(
    this IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector 
); 

作爲其最簡單的理解。有效的代碼會做這樣的事情:

枚舉通過source

對於源中的每個element,地圖元素key = keySelector(element)

看看key是由TKey 鍵控字典,如果它不是,添加key,其中值爲a List<TSource>和第一項element 否則,獲取與密鑰關聯的List<TSource>並將element添加到列表

現在你有了一個字典映射TKey - >TSource並且可以很容易地產生一個序列IGrouping<TKey, TElement>

因此,像

var dictionary = new Dictionary<TKey, List<TSource>> dictionary; 
foreach(var element in source) { 
    key = keySelector(element); 
    List<TSource> list; 
    if(!dictionary.TryGetValue(key, out list)) { 
     list = new List<TSource>(); 
     dictionary.Add(key, list); 
    } 
    list.Add(element); 
} 

從這裏你可以輕鬆獲得的IGrouping<TKey, TSource>序列。

我不明白你爲什麼認爲列表正在排序很重要。

+1

如果列表進行排序,我們可以得到IGrouping不處理整個列表 – SiberianGuy 2011-05-20 19:58:01

+0

@Idsa:解釋。 – jason 2011-05-20 20:32:12

+1

如果列表按鍵排序,並且您知道它,則可以創建一個IGrouping對象,然後在鍵值更改後立即「返回」,然後開始新的IGrouping。 @Idsa - 製作「GroupBySorted」擴展方法並不難,然後對其進行配置以查看它是否比常規的GroupBy具有任何實際優勢... – 2011-05-20 21:33:31

0

它看起來每個關鍵的整個集合?

號的GroupBy的實施,爲O(n),而不是爲O(n^2)