Ruby Enumeration: Taken first n where block returns true

落花浮王杯 提交于 2019-12-10 21:19:20

问题


I want to take the first "n" entries which pass the block

a = 1..100_000_000 # Basically a long array

# This iterates over the whole array -- no good
b = a.select{|x| x.expensive_operation?}.take(n)

I want to short circuit the iteration once i've got n entries where 'expensive' condition is true.

What do you suggest? take_while and keep count of n?

# This is the code i have; which i think can be written better, but how?
a = 1..100_000_000 # Basically a long array
n = 20
i = 0
b = a.take_while do |x|
  ((i < n) && (x.expensive_operation?)).tap do |r|
    i += 1
  end
end

回答1:


Ruby 2.0 implements lazy enumerables, for older versions use the gem enumerable-lazy:

require 'enumerable/lazy'
(1..Float::INFINITY).lazy.select(&:even?).take(5).to_a
#=> [2, 4, 6, 8, 10]



回答2:


It should work with a simple for loop and a break :

a = 1..100_000_000 # Basically a long array
n = 20
selected = []
for x in a
  selected << x if x.expensive_operation?
  break if select.length == n
end


来源:https://stackoverflow.com/questions/13108521/ruby-enumeration-taken-first-n-where-block-returns-true

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!