Ruby Lazy Enumerable flat_map 不是很懒

标签 ruby lazy-evaluation enumerable

编辑:因为我用错误的例子写了问题并且没有描述我的问题,我会再做一次!

在我看来,#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

这只会考虑到 block 内生成的数组是有限的。但它们也将在 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) 调用将“强制”计算它)。

最佳答案

您实际上并没有使用惰性枚举器。要将普通枚举器转换为惰性枚举器,请使用 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 不是很懒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27384472/

相关文章:

mysql - Rails ActiveRecord - 有没有办法在没有 id 的情况下对表执行操作?

ruby - Ruby SDK 版本 2 中的响应分页是什么?

clojure - 在累加器上进行归约和映射会产生堆栈溢出

swift - 带闭包的惰性变量

scala - Scala 2.10中如何实现惰性val类变量?

javascript - 使属性不可枚举有什么好处?

ruby-on-rails - Ruby 中意外的大小写行为

ruby - 如何在 Ruby 中实现多态性

ruby - Enumerable#sum 如何避免浮点舍入错误?

ruby - 在 Ruby 中反转可枚举