nekoTheShadow’s diary

IT業界の片隅でひっそり生きるシステムエンジニアです(´・ω・`)

rubyで配列どうしの「差分」を求めよう。

注意:この記事は相当「おねむ」な状態で書いています。ただでさえ伝えづらい内容が余計にわけわからなくなっている可能性があります。ごめんね。

rubyのお勉強中、次のようなメソッドが必要になりました。

ary1 = [1,2,2,3]
ary2 = [2,3,4]
p ary1.diff(ary2)
#=> [1,2]

なかなか言葉では表しづらい機能ですね。一応便宜的に配列どうしの「差分」とでも呼んでおきましょう。

さて「差分」を求めるにあたって、わたしは最初次のようなコードを書きました。

ary1 = [1,2,2,3]
ary2 = [2,3,4]
p ary1 - ary2

しかしこれでは何かがおかしい。そう思って原因を調べてみると……

ary1 = [1,2,2,3]
ary2 = [2,3,4]
p ary1 - ary2
#=> [1]

どうやらArray#-ary1ary2で重複している要素をすべてary1から消し去ってしまう模様です。これでは困るというか、すくなくともわたしのいうところの「差分」ではありません。

そうなると「差分」を求めるメソッドは自分で書くほかないということですね。仕方ない。作りましょう。

class Array

  # 配列どうしの「差分」を求めるメソッド。
  # [1,2,2,3].diff([2,3,4]) => [1,2] 
  def diff(ary)
    temp = self.dup # selfの破壊を防ぐため。
    ary.each do |val|
      idx = temp.index(val)
      next if idx == nil # ary2の要素がary1にないときはパス。
      temp.delete_at(idx)
     end
     temp
  end

end

できました。インデックスを利用するのが今回のポイントですね。