2016-08-02 94 views
2

因此,Ruby有一个select方法,可以根据从块传入的条件从数组中选取元素。Ruby选择方法:检查选择的项目数

例如

arr = [1,2,3,4] 
arr.select {|x| x.even? } => [2, 4] 

我的问题涉及大阵,我只希望一定数量的选择项。例如,在阵列之外,我只需要匹配条件的前5个数字。

arr.select{|x| x.even?}[0...5] 

这是我到目前为止。这是非常缓慢的,因为在选择前五个元素之前,Ruby在整个数组上运行select函数。

我想看看是否有办法停止选择功能,当前五个元素被选中。

例如,如果我能做到这一点

res = arr.select do |x| 
    x.even? 
    break if self.length > 5 
end 

在这种情况下,自对res数组的引用。我认为这个参考文件不会起作用,但我希望它能够说明我的观点。

回答

6

在这种情况下,self是对res数组的引用。

Ruby中的关键字self可让您访问当前对象 - 接收当前消息的对象。

我认为这是Enumerator::Lazy工作:

>> (1..100000).lazy.select { |x| x.even? }.first(5) 
=> [2, 4, 6, 8, 10] 
+1

这正是我所需要的。非常感谢你。 – davidhu2000

2

lazy是量身定做的,但你也可以写

1.step.each_with_object([]) do |x, arr| 
    arr << x if x.even? 
    break arr if arr.size == 5 
end 
    #=> [2, 4, 6, 8, 10] 

此外,Enumerator#lazy看到光明的一天在Ruby中v2.0,Enumerable#each_with_object v1.9,Enumerable#reduce(又名inject),它们也可以更早地使用,因此您选择的方法可能取决于您希望支持的最早版本的Ruby。还有一件事:如果效率很重要,您可能需要进行基准测试,因为lazy的声誉相对较慢。