2012-10-28 67 views
3

我要採取的第一個「N」項該塊紅寶石枚舉:先拿n,其中塊返回true

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) 

我想傳遞給短路迭代一次我有n個條目,其中「昂貴「的條件是真的。

你有什麼建議? take_while並保持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 
+0

我在我看來,即使'x.expensive_operation?'是錯誤的,你的解決方案也會選擇一些'x'值...是你想要的嗎? – Baldrick

+0

嗯..你是對的,我的解決方案似乎並不正確,但並不像你所建議的那樣。它會在第一個值處停止,其中expensive_operation是假的,返回的值少於n個值。 –

回答

4

紅寶石2.0工具lazy enumerables,舊版本使用的寶石enumerable-lazy

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

看起來很有希望。未來。 –

1

應該用一個簡單的for循環的工作方式和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