ruby2.2から使えるslice_afterが便利そうだなと思ったら、既にslice_beforeがあった件

「要素をn個ごとに区切って配列にする」という処理ではEnumerable#each_sliceが便利ですが、これを「n個」とかではなく、パターンマッチで区切りたいなーと思うことがあると思います。で、Ruby 2.2.0-preview1 Releasedで「へー、Enumerable#slice_afterってのが追加されるんだ」とRuby2.2からやっとパターンマッチで区切れるようなメソッドが追加されるのかと思ったら、既にEnumerable#slice_beforeがあったよ、という話。

slice_beforeとslice_after

知らなかったslice_beforeというのはこんな奴(参考:リファレンス

# 偶数要素をチャンクの先頭と見なす
[0,2,4,1,2,4,5,3,1,4,2].slice_before(&:even?).to_a
# => [[0], [2], [4, 1], [2], [4, 5, 3, 1], [4], [2]]

# 奇数要素をチャンクの先頭と見なす
[0,2,4,1,2,4,5,3,1,4,2].slice_before(&:odd?).to_a
# => [[0, 2, 4], [1, 2, 4], [5], [3], [1, 4, 2]]

日付が切り替わったときにブレイクする、みたいな条件はslice_before(initial_state) {|elt, state| bool } -> Enumeratorを利用すれば書けます。Enumerable#group_byばっかり使ってたな。。

slice_beforeに対して、Ruby2.2から標準実装されるslice_afterはこんな振る舞いをします。

# 真になった時点で区切る
[0,2,4,1,2,4,5,3,1,4,2].slice_after(&:even?).to_a
# => [[0], [2], [4], [1, 2], [4], [5, 3, 1, 4], [2]]

何らかの明細を表示するときなんかのラインブレイクがより流暢に書けそうですね。