ToLookup是否强制立即执行序列 [英] Does ToLookup forces immediate execution of a sequence

查看:36
本文介绍了ToLookup是否强制立即执行序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 Enumerable.ToLookup API,该API将可枚举的序列转换为字典类型的数据结构.可以在此处找到更多详细信息:

https://msdn.microsoft.com/zh-CN/library/system.linq.enumerable.tolookup(v=vs.110).aspx

它唯一的区别在于 ToDictionary API是这样的事实:如果键选择器产生重复的键,则它不会给出任何错误.我需要比较这两个API的延迟执行语义.AFAIK ToDictionary API可以立即执行序列,即不遵循LINQ查询的延迟执行语义.任何人都可以帮助我解决 ToLookup API 的延迟执行行为吗?是否与 ToDictionary API相同或有什么不同?

解决方案

易于测试...

  void Main(){var lookup = Inf().ToLookup(i => i/100);Console.WriteLine(如果看到此消息,则将ToLookup推迟");//永远不会发生}IEnumerable< int>Inf(){未检查{for(var i = 0 ;; i ++){收益率}}} 

回顾一下, ToLookup greedily 会使用源序列而不进行延迟.

相反, GroupBy 运算符 被推迟,因此您可以编写以下内容,以免产生不良影响:

  var groups = Inf().GroupBy(i => i/100);//哎呀 

但是, GroupBy 贪婪,因此当您枚举时,整个源序列都会被消耗.

这意味着

  groups.SelectMany(g => g).First(); 

也无法完成.

考虑分组问题时,很快就会发现,将序列分为一组序列时,如果不完全消耗整个序列就不可能知道即使只有一个组是完整的./p>

I was looking into Enumerable.ToLookup API which converts an enumerable sequence into a dictionary type data structure. More details can be found here:

https://msdn.microsoft.com/en-us/library/system.linq.enumerable.tolookup(v=vs.110).aspx

The only difference it carries from ToDictionary API is the fact that it won't give any error if the key selector results in duplicate keys. I need a comparison of deferred execution semantics of these two APIs. AFAIK ToDictionary API results in immediate execution of sequence i.e. it doesn't follow deferred execution semantics of LINQ queries. Can anyone help me with the deferred execution behavior of ToLookup API? Is it the same as ToDictionary API or any different?

解决方案

Easy enough to test...

void Main()
{
    var lookup = Inf().ToLookup(i => i / 100);
    Console.WriteLine("if you see this, ToLookup is deferred"); //never happens
}

IEnumerable<int> Inf()
{
    unchecked
    {
        for(var i=0;;i++)
        {
            yield return i;
        }
    }
}

To recap, ToLookup greedily consumes the source sequence without deferring.

In contrast, the GroupBy operator is deferred, so you can write the following to no ill-effect:

var groups = Inf().GroupBy(i => i / 100); //oops

However, GroupBy is greedy, so when you enumerate, the entire source sequence is consumed.

This means that

groups.SelectMany(g=>g).First();

also fails to complete.

When you think about the problem of grouping, it quickly becomes apparent that when separating a sequence into a sequence of groups, it would be impossible to know if even just one of the groups were complete without completely consuming the entire sequence.

这篇关于ToLookup是否强制立即执行序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆