ruby - 如何在没有迭代器的情况下在 Ruby 中收集 block 值?

标签 ruby

这是一些代码:

i = 0
collection = []
loop do
  i += 1
  break if complicated_predicate_of(i)
  collection << i
end
collection

我事先不知道需要迭代多少次;这取决于complicated_predicate_of(i)。我可以做类似 0.upto(Float::INFINITY).times.collect do ... end 的事情,但这非常难看。

我想这样做:

i = 0
collection = loop.collect do
  i += 1
  break if complicated_predicate_of(i)
  i
end

但是,尽管由于某种原因这不是语法错误,但 loop.collect 似乎没有收集任何内容。 (loop.reduce 也没有)。语句末尾的 collection 为 nil。

换句话说,我想在没有显式迭代器的情况下收集loop语句的值。有什么办法可以实现这一点吗?

最佳答案

你可以这样写

collection = 1.step.take_while do |i| 
  i <= 3 # this block needs to return *false* to stop the taking
end

无论您最终选择什么解决方案,请记住您始终可以选择引入具有不言自明的名称的辅助方法。特别是如果您需要在源代码中的许多地方收集这样的数字。

假设您想隐藏上面解决方案的复杂内部,那么这可能是您的辅助方法:

def numbers_until(&block)
  i = 0
  collection = []
  loop do
    i += 1
    break if yield i
    collection << i
  end
  collection
end

collection = numbers_until do |i|
   i > 3 # this block needs to return *true* to stop the taking
end

关于ruby - 如何在没有迭代器的情况下在 Ruby 中收集 block 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42520499/

相关文章:

ruby-on-rails - Rails The Movie Database Gem 按受欢迎程度排序

Ruby 创建方程图像 (LaTeX)

ruby - FactoryBot 的随机特征

ruby-on-rails - 关于个人资料图片系统的建议(Rails 3)

ruby - 如何让 rspec 不显示数据库查询而只显示带有 rails_12factor 的点?

ruby - 如何自定义 ruby pry 石的颜色?

ruby-on-rails - rails : How to observe join records that don't actually have a Model?

ruby - 如何在 Nokogiri 中创建 <text>...</text> 节点?

Ruby - 优化两个数组重复项的比较

ruby - 在 Rails 订购系统中模拟销售税的最佳方式是什么