Ruby 2.0の最も特徴的な新機能の1つ、lazyを使ってみましょう。
いかにもわざとらしい例ですが、まずはフィボナッチ数列を10個表示してみます。
fib = Enumerator.new do |y|
i1 = 0
i2 = 1
y << 1
loop do
i3 = i1 + i2
i1 = i2
i2 = i3
y << i3
end
end
> p fib.each.take(10).to_a
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
これは簡単ですね。
次に、フィボナッチ数列から偶数のみ10個取り出してみます。
奇数→奇数→偶数の順で現れるのは明白ですが、ここではその規則を知らないつもりで。素数とかにすれば良いんですがコードが多くなるので・・
> p fib.each.select{|i| i.even?}.take(10).to_a
無限ループ!
無限ループになってしまいました。
selectは事前に値がそろってないと使えませんね。
lazyを使って書き直してみます。
> p fib.each.lazy.select{|i| i.even?}.take(10).to_a
[2, 8, 34, 144, 610, 2584, 10946, 46368, 196418, 832040]
簡単に計算できました。便利ですね。
実際に、DBからLIMIT付で値を取得する際に、DB側のSELECTだけでは絞り込みができない場合などにも使えそうです。
1件ごと取得になるので重いですが、データ件数がたとえば1000万件なら、全件取得してから絞り込むよりも現実的に使える可能性があります。