我有一个非常大的范围需要遍历并找到满足特定约束的第一个元素.这在Ruby中已经可以高效地完成了.

# Runs until memory is exhausted _without_ lazy!
(1..).lazy.select { |i| i > 5 }.first
# => 6

然而,在我的用例中,我希望从范围的random interval开始迭代,如果到达范围末尾时没有元素通过判断,则从范围的开始处继续(直到再次达到随机间隔,如果需要).以Combining two different 'ranges' to one in ruby作为参考,我来到了...

letter = ('b'..'y').to_a.sample
[*letter..'z', *'a'...letter].map { |c| c.capitalize }.join
# => "FGHIJKLMNOPQRSTUVWXYZABCDE"

当然,我没有字母表作为遍历的范围,这只是一个小规模的例子,在我的用例中失败了.

  • *(Splat)操作员并不懒
  • map不是懒惰

通过更多的谷歌搜索和实验,我得出了以下 struct :

# lazy version of previous alphabet example
[(letter..'z'), ('a'...letter)].lazy.flat_map { |r| r.each.lazy }.map { |c| c.capitalize }.force.join
=> "FGHIJKLMNOPQRSTUVWXYZABCDE"

# Comparable to what I want
start = rand(2**64)
# => 15282219649142738977
[(start..2**64), (0...start)].lazy.flat_map { |r| r.each.lazy }.select { |i| i % 7 == 0 }.first(5)
# => [15282219649142738978, 15282219649142738985, 15282219649142738992, 15282219649142738999, 15282219649142739006]
iter = [(start..2**64), (0...start)].lazy.flat_map { |r| r.each.lazy }.select { |i| i % 7 == 0 }
# => #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: [15282219649142738977..18446744073709551616, 0...15282219649142738977]>:flat_map>:select>
iter.next
# => 15282219649142738978
iter.next
# => 15282219649142738985

在我看来,这确实太复杂了,也许有人有更好的主意?

Thank you for your time,
Xavier.

推荐答案

你可以用Enumerable#chain

>> start = rand(2**64)
=> 9019096319891825624

>> (start..2**64).chain(0...start).lazy.select { |i| i % 7 == 0 }.first(3)
=> [9019096319891825629, 9019096319891825636, 9019096319891825643]

>> Enumerator::Chain.new(start..2**64, 0...start).lazy.select { |i| i % 7 == 0 }.first(3)
=> [9019096319891825629, 9019096319891825636, 9019096319891825643]

Ruby相关问答推荐

Ruby PKCS7:添加;\r〃;字节正在 destruct 解密

从整数中 Select 重复数字的字符串

字符串长度多显示一个字符 - ruby

如何使用 define_method 指定方法默认参数?

冒号:和粗箭头=>有什么区别

Ruby:通过正则表达式过滤数组?

Ruby 中的 Fail vs. raise:我们真的应该相信风格指南吗?

删除 Ruby 数组中的 nil 和空白字符串

将字符串与多个模式匹配

Ruby 运算符优先级表

如何使用 Ruby 2.3 中引入的 Array#dig 和 Hash#dig?

如何从 SystemStackError 中获取回溯:堆栈级别太深?

如何在 RSpec 2 中自动加载 spec_helper.rb

在 Ruby 中按名称获取一个类?

如何在数组中找到出现次数最多的项目

Mountain Lion rvm 安装 1.8.7 x11 错误

正则表达式,如何匹配多行?

在 Ruby 中,获取数组中最大值的索引的最简洁方法是什么?

查找模块中可用的类

查找两个数组的共同点