Ruby Lazy Enumerable flat_map 不是很懒
Posted
技术标签:
【中文标题】Ruby Lazy Enumerable flat_map 不是很懒【英文标题】:Ruby Lazy Enumerable flat_map is not very lazy 【发布时间】:2015-02-07 16:06:55 【问题描述】:编辑:由于我用错误的示例写了问题并且没有描述我的问题,我会再做一次!
在我看来,#flat_map 尽管是 Enumerator::Lazy 类的一部分,但它本身并不是非常可枚举的。
这个例子可以正常工作:
(1..Float::INFINITY).flat_map |s| [s,s] .take(4).to_a
惰性实现也可以:
(1..Float::INFINITY).flat_map |s| [s,s] .take(4).to_a
这只会考虑块内生成的数组是有限的。但它们也将在 take(4) 调用发生之前进行全面评估。这不是很懒惰。
因此,这将失败:
(1..Float::INFINITY).lazy.flat_map |i| (i..Float::INFINITY).map(&:to_i) .take(4).force
因为“数组的无穷大范围”将在惰性调用发生之前被完全评估。不过,我希望它“默认是懒惰的”。我的意思是,我确实理解难题所在,但我希望它会以这种方式发生:flat_map 评估每个实例惰性,知道结果将是一个数组(或至少是可枚举的),并将应用惰性机制在上面。因此, (i..Float::INFINITY).map(&:to_i) 将被惰性化(这似乎不太兼容,因为 map(&:to_i) 调用将“强制”计算它)。
【问题讨论】:
这可能是实现中的错误。 @tadman:OP 是flat_map
ping Range
,而不是Enumerator::Lazy
。这里根本没有懒惰,你也不希望有。
耶稣,现在才注意到缺少的#lazy 调用...我将不得不回到我失败的示例,看看我最初的问题是什么。
很抱歉,我在包装惰性集合时遇到了问题。我会尝试重写
前两行代码不完全一样吗?为什么你说一个是懒惰的而另一个不是
【参考方案1】:
您实际上并没有使用惰性枚举器。要将普通枚举器转换为惰性枚举器,请使用Enumerable#lazy
方法。为了得到结果,我建议使用 Enumerable::Lazy#force
而不是 to_a
方法,因为我认为它更清楚地表明了意图。
(1..Float::INFINITY).lazy.flat_map |s| [s,s] .take(4).force
#=> [1, 1, 2, 2]
【讨论】:
以上是关于Ruby Lazy Enumerable flat_map 不是很懒的主要内容,如果未能解决你的问题,请参考以下文章