LINQ To Objects GroupBy方法

时间:2011-05-20 19:25:37

标签: c# .net linq

LINQ To Objects Group By方法如何工作?每个键都可以查看整个集合吗?有没有办法对GroupBy方法说集合是否已排序?

3 个答案:

答案 0 :(得分: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));
}

基本上按键分组,为每个唯一键创建一个包含值的列表。

可以做一些事情,比如与最后看到的密钥进行比较(以帮助排序数据),但是......你需要进行剖析才能知道它是否值得。

答案 1 :(得分: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的{​​{1}}和第一项List<TSource>     否则,获取与密钥相关联的element并将List<TSource>添加到列表

现在你有一个字典映射element - &gt; 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); }

我不明白为什么你认为正在排序的列表很重要。

答案 2 :(得分:0)

是否可以查看每个密钥的整个集合?

没有。 GroupBy的实现是O(n),而不是O(n ^ 2)