LINQ To Objects Group By方法如何工作?每个键都可以查看整个集合吗?有没有办法对GroupBy方法说集合是否已排序?
答案 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)