首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >array.select n元素最多

array.select n元素最多
EN

Stack Overflow用户
提问于 2013-11-06 22:11:43
回答 3查看 139关注 0票数 2

考虑一个带有大量元素的的Ruby数组。

我希望对数组进行反向迭代,并选择给定块返回true的前n个结果。

例如。

代码语言:javascript
复制
seniors = persons.reverse.select do |person|
  person.age > 60
end

这是可以的,但是它收集了所有的老年人,而不是最多的n名老年人。当收集到n个结果时,提前终止迭代的最好方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-06 22:21:00

代码语言:javascript
复制
seniors = []
persons.reverse.each{ |p| 
  seniors << p if p.age > 60
  break if seniors.count >= n
}
票数 3
EN

Stack Overflow用户

发布于 2013-11-06 23:46:33

懒惰评价很棒,因为它可以在不改变通常用于严格计算的抽象的情况下编写这类代码(Haskell已经证明了这是多么强大)。幸运的是,Ruby2.0将在这方面附带一些基础设施,当这一时刻到来时,您将能够编写以下内容:

代码语言:javascript
复制
# Ruby >= 2.0
seniors = persons.reverse.lazy.select { |person| person.age > 60 }.take(n)

对于Ruby < 2.0:https://github.com/yhara/enumerable-lazy

票数 2
EN

Stack Overflow用户

发布于 2013-11-06 22:59:46

您可以连锁take_whileeach_with_object

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19823896

复制
相关文章

相似问题

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