开发者

LINQ To Objects GroupBy method

How does LINQ To Objects GroupBy method work? Does it look throught the whole collection for each key? Is there any way to say to GroupBy开发者_如何学Go method that collection is sorted?


GroupBy, if done sensibly, would work in a single forwards only pass. A basic implementation (not theirs) would be something comparable to:

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

That basically groups by key, creating a list for each unique key, containing the values.

You could do things like compare to the last-seen key (to help with sorted data), but... you'd need to profile to know if it is worthwhile.


Let's just look at the overload

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

as its the simplest to understand. Effectively the code will do something like this:

Enumerate through source

For each element in source, map element to key = keySelector(element)

See if key is in a dictionary keyed by TKey if it is not, add the key with the value a List<TSource> and first item element else, get the List<TSource> associated to key and add element to the list

Now you have a dictionary mapping TKey -> TSource and can easily produce a sequence of IGrouping<TKey, TElement>.

So something like

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

From here you can easily yield a sequence of IGrouping<TKey, TSource>.

I don't see why you think the list being sorted matters.


Does it look throught the whole collection for each key?

No. The implementation of GroupBy is O(n), not O(n^2)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜