先に使い方を考えた。
# ブロックなしだと `succ` で進める
builis( 0 ).take(5)
#=> [0,1,2,3,4]
# ブロックなしだと `succ` で進めるので、文字も使える
builis(?a).lazy.zip((1..3).cycle).map( &:join ).take(10).force
#=> ["a1", "b2", "c3", "d1", "e2", "f3", "g1", "h2", "i3", "j1"]
# ブロックありだと、ブロックの評価結果を次の要素にする
builis( 11 ){ |x| [x/2,x*3+1][x%2] }.take_while{ |x| x!=1 }
#=> [11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2]
こんなの。
名前は、build list から。
実装はこんな具合
def builis( start )
Enumerator.new do |y|
i=start
loop{
y<<i
i = block_given? ? yield(i) : i.succ
}
end
end
便利かどうかはよくわかってない。
使用例追加:
#みんな大好きフィボナッチ
builis([0,1]){|x|[x[1],x[0]+x[1]]}.take(15).map(&:first)
#=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
#みんな大好きフィボナッチもう一つ
builis([]){|x| [x,x[0]]}.take(15).map{|x|x.flatten.size}
#=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]