参考もと様の記事を眺めていたところ、chunkというメソッドを発見。
チャンクという位ですから、意味合いレベルのカタマリを作ってくれるものと考えられます。
試しに公式を見に行ったところ
要素を前から順にブロックで評価し、その結果によって 要素をチャンクに分けた(グループ化した)要素を持つ Enumerator を返します。
とのこと。サンプルとして、以下のように偶数か判定して多重配列をつくるものが...
[3,1,4,1,5,9,2,6,5,3,5].chunk {|n| n.even? }.each {|even, ary| p [even, ary] } #=> [false, [3, 1]] # [true, [4]] # [false, [1, 5, 9]] # [true, [2, 6]]
な、なにこれ...?
遊んでみる
chunk {|a,b| key}
> %w(a b c).chunk {|i| i}.each { |a, b| p a,b } "a" ["a"] "b" ["b"] "c" ["c"] => nil
chunkに渡すブロックで小分け条件を指定、
> %w(as you like).chunk {|i| i.length > 3}.each do |a, b| p [a, b] end [false, ["as", "you"]] [true, ["like"]] => nil
ブロックなのでprocオブジェクトを渡す事もできます。
chunk_with_objectなんてのは流石に無さそうですが。
> (1..10).map.chunk(&:odd?).each {|a, b| p [a, b]} [true, [1]] [false, [2]] [true, [3]] [false, [4]] [true, [5]] [false, [6]] [true, [7]] [false, [8]] [true, [9]] [false, [10]] => nil
chunk(initial_state){|a,b| key}
enum.chunk(initial_state) {|elt, state| key }.each {|key, ary| ... }
とあるように、初期値を渡す事も可能です。
> %w(a b c d).chunk('c'){|elt,state|elt == state}.each {|key, ary| p key,ary}
状態遷移図のような複雑な事も出来ます。
> flag = 1; ('a'..'z').chunk(['c','w']){|elt,state| \ case flag when 1 then elt == state[0]; flag = 2 when 2 then elt == state[1] end }.each{|a,b| p a,b} 2 ["a"] false ["b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v"] true ["w"] false ["x", "y", "z"] => nil