Ruby 2.3.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Enumerableモジュール > chunk_while

instance method Enumerable#chunk_while

chunk_while {|elt_before, elt_after| ... } -> Enumerator[permalink][rdoc]

要素を前から順にブロックで評価し、その結果によって要素をチャンクに分け た(グループ化した)要素を持つEnumerator を返します。

隣り合う値をブロックパラメータ elt_before、elt_after に渡し、ブロックの 評価値が偽になる所でチャンクを区切ります。

ブロックは self の長さ - 1 回呼び出されます。

[RETURN]
チャンクごとの配列をブロックパラメータに渡す Enumerator を返します。eachメソッドは以下のように呼び出します。
  enum.chunk_while { |elt_before, elt_after| bool }.each { |ary| ... }
to_a や map などのその他の Enumerable モジュールのメソッ ドも有用です。

例:

# 1ずつ増加する部分配列ごとに分ける。
a = [1,2,4,9,10,11,12,15,16,19,20,21]
b = a.chunk_while {|i, j| i+1 == j }
p b.to_a # => [[1, 2], [4], [9, 10, 11, 12], [15, 16], [19, 20, 21]]
c = b.map {|a| a.length < 3 ? a : "#{a.first}-#{a.last}" }
p c # => [[1, 2], [4], "9-12", [15, 16], "19-21"]
d = c.join(",")
p d # => "1,2,4,9-12,15,16,19-21"

# 増加のみの部分配列ごとに分ける。
a = [0, 9, 2, 2, 3, 2, 7, 5, 9, 5]
p a.chunk_while {|i, j| i <= j }.to_a
# => [[0, 9], [2, 2, 3], [2, 7], [5, 9], [5]]

# 隣り合う偶数同士、奇数同士の部分配列ごとに分ける。
# (Enumerable#chunk を使って実現する事も可能)
a = [7, 5, 9, 2, 0, 7, 9, 4, 2, 0]
p a.chunk_while {|i, j| i.even? == j.even? }.to_a
# => [[7, 5, 9], [2, 0], [7, 9], [4, 2, 0]]

Enumerable#slice_when はブロックの戻り値が真ではなく偽の時に要素 を分ける事を除いて同じ処理を行います。

[SEE_ALSO] Enumerable#slice_when, Enumerable#chunk