array.select最多选择n个元素

时间:2013-11-06 22:11:44

标签: ruby arrays collections

考虑使用很多元素的Ruby数组。

我想反复迭代数组并选择给定块返回true的前n个结果。

E.g。

seniors = persons.reverse.select do |person|
  person.age > 60
end

这没关系,但它收集了所有老年人,而不是最多n个老年人。当收集到n个结果时,过早终止迭代的最好方法是什么?

3 个答案:

答案 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_whileeach_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