首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ILookup<TKey,TVal>与IGrouping<TKey,TVal>

ILookup<TKey,TVal>与IGrouping<TKey,TVal>
EN

Stack Overflow用户
提问于 2009-08-26 21:16:31
回答 3查看 12.2K关注 0票数 83

我一直难以阐明ILookupIGrouping之间的区别,我很好奇我现在是否正确地理解了它。LINQ通过生成IGrouping项的序列,同时给出了ToLookup扩展方法,从而使问题更加复杂。所以在我仔细观察之前他们感觉是一样的。

代码语言:javascript
复制
var q1 = 
    from n in N
    group n by n.MyKey into g
    select g;
// q1 is IEnumerable<IGrouping<TKey, TVal>>

相当于:

代码语言:javascript
复制
var q2 = N.GroupBy(n => n.MyKey, n => n);
// q2 is IEnumerable<IGrouping<TKey, TVal>>

看起来很像:

代码语言:javascript
复制
var q3 = N.ToLookup(n => n.MyKey, n => n);
// q3 is ILookup<TKey, TVal>

下面的类比我是正确的吗?

  1. IGrouping<TKey, TVal>是单个组(即键控序列),类似于KeyValuePair<TKey, TVal>,其中值实际上是元素序列(而不是单个元素)。
  2. IEnumerable<IGrouping<TKey, TVal>>是这些序列的一个序列(类似于在IDictionary<TKey, TVal>上迭代时得到的结果)。
  3. ILookup<TKey, TVal>更像是一个IDictionary<TKey, TVal>,其中的值实际上是一个元素序列。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-08-26 21:21:55

是的,所有这些都是正确的。

ILookup<TKey, TValue>还扩展了IEnumerable<IGrouping<TKey, TValue>>,这样您就可以遍历所有的键/集合对,以及(或代替)查找特定的键。

我基本上认为ILookup<TKey,TValue>就像IDictionary<TKey, IEnumerable<TValue>>一样。

请记住,ToLookup是“立即执行”操作(立即执行),而GroupBy是延迟执行的。碰巧的是,按照“拉LINQ”的工作方式,当您开始从一个IGrouping的结果中提取GroupBy时,它无论如何都必须读取所有的数据(因为您不能在中间切换组),而在其他实现中,它可能能够产生一个流结果。(在Push LINQ中是这样的;我希望LINQ对事件的影响是相同的。)

票数 80
EN

Stack Overflow用户

发布于 2018-08-08 09:15:12

GroupByToLookUp的功能几乎相同--,除了参考文献

GroupBy: GroupBy运算符根据某些键值返回元素组。每个组都由IGrouping对象表示。 ToLookup: ToLookup与GroupBy相同;唯一的区别是GroupBy的执行被推迟,而ToLookup的执行是直接的。

让我们使用示例代码清除差异。假设我们有一个类表示Person模型:

代码语言:javascript
复制
class Personnel
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public int Level { get; set; }
}

之后,我们定义了一个personnels列表,如下所示:

代码语言:javascript
复制
 var personnels = new List<Personnel>
    {
        new Personnel { Id = 1, FullName = "P1", Level = 1 },
        new Personnel { Id = 2, FullName = "P2", Level = 2 },
        new Personnel { Id = 3, FullName = "P3", Level = 1 },
        new Personnel { Id = 4, FullName = "P4", Level = 1 },
        new Personnel { Id = 5, FullName = "P5", Level =2 },
        new Personnel { Id = 6, FullName = "P6", Level = 2 },
        new Personnel { Id = 7, FullName = "P7", Level = 2 }
    };

现在,我需要将personnels按其级别分组。我这里有两条路。使用GroupByToLookUp。如前面所述,如果我使用GroupBy,它将使用延迟执行,这意味着,当您遍历集合时,下一个项可能被计算出来,也可能不会被计算,直到被调用为止。

代码语言:javascript
复制
 var groups = personnels.GroupBy(p => p.Level);
    personnels.RemoveAll(p => p.Level == 1);
    foreach (var product in groups)
    {
        Console.WriteLine(product.Key);
        foreach (var item in product)
            Console.WriteLine(item.Id + " >>> " + item.FullName + " >>> " + item.Level);
    }

在上面的代码中,我首先对personnels进行分组,但是在迭代它之前,我删除了一些personnels。由于GroupBy使用延迟执行,所以最终结果将不包括删除的项,因为分组将在此处的foreach点中进行计算。

输出:

代码语言:javascript
复制
2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2

但是,如果我按照以下方式重写上面的代码:(请注意,除了GroupBy之外,代码与以前的代码相同,由ToLookUp替换)

代码语言:javascript
复制
 var groups = personnels.ToLookup(p => p.Level);
    personnels.RemoveAll(p => p.Level == 1);
    foreach (var product in groups)
    {
        Console.WriteLine(product.Key);
        foreach (var item in product)
            Console.WriteLine(item.Id + " >>> " + item.FullName + " >>> " + item.Level);
    }

由于ToLookUp使用立即执行,这意味着当我调用ToLookUp方法时,生成结果并应用组,因此如果在迭代之前从personnels中删除任何项,则不会影响最终结果。

输出:

代码语言:javascript
复制
1
1 >>> P1 >>> 1
3 >>> P3 >>> 1
4 >>> P4 >>> 1
2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2

注意:GroupByToLookUp也都返回不同的类型。

您可能使用ToDictionary而不是ToLookUp,但是您需要注意以下几点:(参考文献)

ToLookup()的用法非常类似于ToDictionary(),两者都允许您指定键选择器、值选择器和比较器。主要区别是ToLookup()允许(并期望)重复键,而ToDictionary()不允许重复键

票数 11
EN

Stack Overflow用户

发布于 2013-06-05 16:00:57

ILookup和IDictionary还有另一个重要的区别:前者强制不可变,因为这里没有更改数据的方法(除非使用者执行显式强制转换)。相反,IDictionary有类似于"Add“的方法,这些方法允许更改数据。因此,从函数编程和/或并行编程的角度来看,ILookup更好。

(顺便说一句,似乎值得指出的是,IEnumerable和IList之间的关系有点类似于ILookup和IDictionary之间的关系--前者是不变的,后者则不是。)

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1337539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档