3
2

More than 5 years have passed since last update.

ruby で無限リストを作る

Last updated at Posted at 2013-08-01

先に使い方を考えた。

# ブロックなしだと `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]
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2