個人メモです。
uniqメソッドを使うと重複する要素を排除することができる。
- 非破壊処理。
- ブロックを使って、各要素を処理したあとで比較できる
- 重複する場合は、最初の要素が残る。(後ろの要素を削除)
##配列の場合
arr = [1, 4, 5, 3, 5, 6, 1, 3, 2, 2, 1, 1, 1]
arr.uniq
=> [1, 4, 5, 3, 6, 2]
##非破壊の確認
p arr
=> [1, 4, 5, 3, 5, 6, 1, 3, 2, 2, 1, 1, 1]
**▼処理後の値** ブロックを使うと処理後の値を比較できる。削除するのは該当する元の値。(※処理後ではない)
・オブジェクト.uniq{|変数| 処理}
例えば、文字列が入った要素を、to_s
で全ての要素を文字列にしてから比較する。
arr1 = [1, 3, 2, "2", "3", 1]
arr1.uniq{|i| i.to_s}
=> [1, 3, 2]
元の値 | 1 | 3 | 2 | "2" | "3" | 1 |
---|---|---|---|---|---|---|
処理後 | "1" | "3" | "2" | "2" | "3" | "1" |
残る要素 | ○ | ○ | ○ | × | × | × |
よって出力は重複なしか1つ目に該当する元の値[1, 3, 2]
となる。
##オブジェクトの場合 オブジェクトで値が重複している要素の削除もできる。
・オブジェクト.uniq{|変数1, 変数2| 処理}
- ブロックは必須
- 変数は2つ必須。変数1にキー、変数2に値が入る。
- 出力は配列になるため、
to_h
でオブジェクト(シンボル)に戻す。
###シンボルにする場合
obj = {:a=>1, :b=>2, :c=>3, :d=>2, :f=>3}
obj2 = obj.uniq{|x,y| y}
=> [[:a, 1], [:b, 2], [:c, 3]]}
obj2.to_h
=> {:a=>1, :b=>2, :c=>3}
###ハッシュにする場合 ハッシュにしたい場合は、`to_h`メソッドのブロックでキーに`to_s`を適用し文字列にする。
obj = {:a=>1, :b=>2, :c=>3, :d=>2, :f=>3}
obj.uniq{|x,y| y}.to_h{|k ,v| [k.to_s, v]}
=> {"a"=>1, "b"=>2, "c"=>3}