ruby – 我如何突破地图/收集并返回已经收集到的那一点?

我用代码重写这个问题:

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?
最佳答案
如果你真的意思是“断裂”,[0,1,2,1,0]应该导致[0,1],而不是[0,1,1,0]。我知道的Ruby中唯一的方法是在一个循环中打破。功能性方法可能要慢得多,因为你实际上并不打破:

r = 
  [0,1,2,1,0].inject([true, []]) do |(f, a), i|
    if f
      if i > 1
        [false, a]
      else
        [f, a << i]
      end
    else
      [f, a]
    end
  end
puts r.last.inspect

与之比较:

r = []
[0,1,2,1,0].each do |i|
  break if i > 1
  r << i
end
puts r.inspect

对于Ruby来说,尾随递归是不成问题的,这是用真正的功能语言完成的。

打破地图对我来说无效,结果是零。

添加:正如@dogenpunk指出的那样,有take_while(和drop_while实际上),这可能是一个更好的选择,只有它总是创建临时数组,这可能是也可能不是一个问题。

转载注明原文:ruby – 我如何突破地图/收集并返回已经收集到的那一点? - 代码日志