🐰

【Ruby】配列から重複を削除する uniq は Hash の重複も削除できる

2024/06/05に公開

Ruby で配列から重複する項目を削除する方法を調べたので備忘録としてまとめます。
単にメソッドの紹介だけしても味気ないなと思い、調べたら便利な機能も見つけたのでそれもまとめます。

結論

  • uniq で重複削除, uniq! で破壊的に重複削除
  • ブロックを渡せるので、Hash の配列で Hash の特定のキーの重複とかも削除できる

uniq で重複削除, uniq! で破壊的に重複削除

uniq メソッドを使用することで配列から重複を削除することができます。

arr = ["tanaka", "hanako", "nagata", "tanaka"]
arr2 = arr.uniq
p arr
# ["tanaka", "hanako", "nagata", "tanaka"]
p arr2
# ["tanaka", "hanako", "nagata"]

uniq! メソッドを使用することで元の配列を破壊的に変更します。

arr = ["tanaka", "hanako", "nagata", "tanaka"]
arr2 = arr.uniq!
p arr
# ["tanaka", "hanako", "nagata"]
p arr2
# ["tanaka", "hanako", "nagata"]

ブロックを渡せるので、Hash の配列で Hash の特定のキーの重複とかも削除できる

uniq 自体便利なメソッドでしたが、ブロックを渡せるのがさらに便利だとおもいました。
例えば以下のような Hash の配列があったときでも、キーを指定することで重複を削除することができます。

arr = [{id: 0, name: "tanaka"}, {id: 1, name: "hanako"}, {id: 2, name: "nagata"}, {id: 0, name: "tanaka"}]

arr.uniq { |h| h.id }
# [{id: 0, name: "tanaka"}, {id: 1, name: "hanako"}, {id: 2, name: "nagata"}]

上記のように、ブロック内で id を取り出すことで、Hash 内の id が 配列内で重複していた場合、削除することができます。
なお、uniq メソッドは配列の先頭からたどって重複を削除していき、先に出現したものが残る仕様だそうです。指定するキーには注意が必要ですね~

# 先に出現したものが残る
arr = [{id: 0, name: "tanaka"}, {id: 1, name: "hanako"}, {id: 2, name: "nagata"}, {id: 0, name: "yamada"}]

arr.uniq { |item| item[:id]}
# [{:id=>0, :name=>"tanaka"}, {:id=>1, :name=>"hanako"}, {:id=>2, :name=>"nagata"}]

参考

https://docs.ruby-lang.org/ja/latest/method/Array/i/uniq.html

Discussion