隣り合う要素でグループ分け

0 と 1 からなる配列があります。 たとえば [0, 1, 1, 0, 0, 1, 0, 0] の配列を [[0], [1, 1], [0, 0], [1], [0, 0]] のように 0 と 1 とでグループ分けする関数が必要になったので作ってみました。

def group(xs)
  return [] if xs.empty?
  g = []
  buf = [xs[0]]
  xs.drop(1).each {|e|
    same = yield buf[-1], e
    if same
      buf << e
    else
      g << buf
      buf = [e]
    end
  }
  g << buf
  g
end

実行結果です。

p group([1, 1, 0, 0, 0, 1, 0, 1, 1]) {|a, b| a == b }
#=> [[1, 1], [0, 0, 0], [1], [0], [1, 1]]

# 偶奇でグループ分け
p group([2, 4, 6, 1, 3, 6, 8]) {|a, b| a % 2 == b % 2 }
#=> [[2, 4, 6], [1, 3], [6, 8]]