我用代码重写了这个问题:

many = 1000

# An expensive method.
#
# It returns some data or nil if no result is available.
expensive_method = lambda do
  rand(5) == 0 ? nil : "foo"
end

# Now, let's collect some data and stop collecting when no more data is
# available.

# This is concise but doesn't work.
collection = many.times.map do
  expensive_method.call || break
end

puts collection.is_a? Array # false

# This is less concise but works.
collection = []
many.times do
  collection << (expensive_method.call || break)
end

puts collection.is_a? Array # true

# My inner Rubyist ponders: Is it possible to accomplish this more concisely
# using map?

最佳答案

与其直接使用map,不如建立自己的集合,然后利用break返回一个值来提前终止的事实:

result =
  [0, 1, 2, 1, 0].each_with_object([]) { |val, accumulator|
    if val < 2
      accumulator << val
    else
      break accumulator
    end
  }
result  # => [0, 1]

如果我们只是执行break(而不是break accumulator),则隐式返回nil,而result只会设置为nil

该解决方案的优点是仅分配一个累加器阵列,并且只需要循环一次。

关于ruby - 如何突破 map /收集并返回到目前为止收集到的所有内容?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6668008/

10-14 02:50