首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我如何突破地图/收集并返回到那个点之前收集到的任何东西?

我如何突破地图/收集并返回到那个点之前收集到的任何东西?
EN

Stack Overflow用户
提问于 2011-07-13 00:56:25
回答 5查看 14.6K关注 0票数 28

我正在用代码重写这个问题:

代码语言:javascript
复制
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?
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-06-24 02:36:21

不要直接使用map,而是构建您自己的集合,然后使用break返回值的事实提前中止:

代码语言:javascript
复制
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

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

票数 10
EN

Stack Overflow用户

发布于 2011-07-13 15:02:44

当然,在Ruby中实现这一点的唯一方法似乎是使用filter类型的方法,然后将结果传递给map。我不确定这在1.8中是否有效,但在1.9中您可以:

代码语言:javascript
复制
[0,1,2,1,0].take_while {|val| val < 2}.map(&:some_function)

或者在times示例中

代码语言:javascript
复制
3.times.take_while {|count| count <= 1 } #=> [0,1]
票数 19
EN

Stack Overflow用户

发布于 2011-07-13 02:12:22

代码语言:javascript
复制
irb(main):011:0> 3.times.select {|count| count <= 1}
=> [0, 1]

代码语言:javascript
复制
irb(main):014:0> 3.times.reject {|count| count > 1}
=> [0, 1]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6668008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档