簡體   English   中英

沒有迭代器,如何在Ruby中收集塊值?

[英]How can I collect block values in Ruby without an iterator?

這是一些代碼:

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

你可以寫

def complicated_predicate_of(i)
  i > 3
end

1.step.with_object([]) { |i,collection| complicated_predicate_of(i) ?
  (break collection) : collection << i }
  #=> [1, 2, 3]  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM