Ruby 2.3.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Enumerableモジュール > slice_when
slice_when {|elt_before, elt_after| bool } -> Enumerator
[permalink][rdoc]要素を前から順にブロックで評価し、その結果によって要素をチャンクに分け た(グループ化した)要素を持つEnumerator を返します。
隣り合う値をブロックパラメータ elt_before、elt_after に渡し、ブロックの 評価値が真になる所でチャンクを区切ります。
ブロックは self の長さ - 1 回呼び出されます。
enum.slice_when { |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.slice_when {|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" # ソート済の配列を近い値(差が6以内)の部分配列ごとに分ける。 a = [3, 11, 14, 25, 28, 29, 29, 41, 55, 57] p a.slice_when {|i, j| 6 < j - i }.to_a # => [[3], [11, 14], [25, 28, 29, 29], [41], [55, 57]] # 増加のみの部分配列ごとに分ける。 a = [0, 9, 2, 2, 3, 2, 7, 5, 9, 5] p a.slice_when {|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.slice_when {|i, j| i.even? != j.even? }.to_a # => [[7, 5, 9], [2, 0], [7, 9], [4, 2, 0]] # 段落(空行が後ろに続く非空行の文字列)ごとに分ける。 # (Enumerable#chunk で空行を無視して実現する事も可能) lines = ["foo\n", "bar\n", "\n", "baz\n", "qux\n"] p lines.slice_when {|l1, l2| /\A\s*\z/ =~ l1 && /\S/ =~ l2 }.to_a # => [["foo\n", "bar\n", "\n"], ["baz\n", "qux\n"]]
Enumerable#chunk_while はブロックの戻り値が偽ではなく真の時に要 素を分ける事を除いて同じ処理を行います。
[SEE_ALSO] Enumerable#chunk_while, Enumerable#chunk