考虑使用很多元素的Ruby数组。
我想反复迭代数组并选择给定块返回true的前n个结果。
E.g。
seniors = persons.reverse.select do |person|
person.age > 60
end
这没关系,但它收集了所有老年人,而不是最多n个老年人。当收集到n个结果时,过早终止迭代的最好方法是什么?
答案 0 :(得分:3)
seniors = []
persons.reverse.each{ |p|
seniors << p if p.age > 60
break if seniors.count >= n
}
答案 1 :(得分:2)
Lazy evaluation非常棒,因为它可以编写这种代码而无需更改通常在严格评估中使用的抽象(Haskell证明了它的强大程度)。令人高兴的是,Ruby 2.0将在这方面附带一些基础设施,届时你将能够写下这个:
# Ruby >= 2.0
seniors = persons.reverse.lazy.select { |person| person.age > 60 }.take(n)
对于Ruby&lt; 2.0:https://github.com/yhara/enumerable-lazy
答案 2 :(得分:1)
您可以链接take_while
和each_with_object
:
seniors = []
persons.take_while.each_with_object(seniors) do |e, o|
o << e if e.age > 60 && o.count < 1000
o.count < 1000
end
require 'ostruct'
require 'benchmark'
persons = 1000000.times.map {|i| OpenStruct.new age: Random.rand(50..85) }
Benchmark.bm do |b|
b.report do
seniors = []
persons.take_while.each_with_object(seniors) do |e, o|
o << e if e.age > 60 && o.count < 1000
o.count < 1000
end
end
end
#=> finishes in 1-3ms on my machine