💫

uniqとcompactを同時に使えない場合もある?

2024/11/13に公開
2

uniqメソッド

配列から重複を取り除いて、新たな配列を返すメソッドのこと
https://docs.ruby-lang.org/ja/latest/method/Array/i/uniq.html

compactメソッド

配列からnilを取り除いて、新たな配列を返すメソッドのこと
https://docs.ruby-lang.org/ja/latest/method/Array/i/compact.html

同時に使えなかった状況

配列の要素によっては、同時に使えない場合があった。。。

配列に重複もnilもあるとき、同時に使える。

[ 1, 2, 3, 4, 2, nil ].compact!.uniq!
=> [ 1, 2, 3, 4 ]

重複のみで、nilはなかった時、NoMethodErrorになる。

[ 1, 2, 3, 4, 2 ].compact!.uniq!
=> NoMethodError: undefined method `uniq!' for nil

これは、[ 1, 2, 3, 4, 2 ].compact! => nilとなり、nilに対してuniqメソッドを使ってしまうことになるため、エラーになる。

これと同様の理由で、重複がなく、nilがある時、.uniq!.compact!とするとエラーになる。

[ 1, 2, 3, 4, nil ].uniq!.compact!
=> NoMethodError: undefined method `compact!' for nil

以下のような順でメソッドを組み合わせると、

arr = [ 1, 2, 3, 4, 2 ]
arr.uniq!.compact!
=> nil
arr
=> [1, 2, 3, 4]

エラーにはならず、nilになるが、配列arrは重複が除かれて返ってくる。

同様に、

arr = [ 1, 2, 3, 4, nil ]
arr.compact!.uniq!
=> nil
arr
=> [1, 2, 3, 4]

使える方法(追記)

コメントでいただいているように、!をつけずに、.compact.uniqとすれば、同時に使えます!

まとめ

配列の要素がどんなものが入るかによって、メソッドの種類や順番を考えていこうと思います。

Discussion

Junichi ItoJunichi Ito

@phoenix さん、こんにちは。

この件ですが、「どうしても」という理由がなければ!の付かない、ただのuniqcompactを使った方がいいです。

!付きのメソッドがnilを返すのは、「!付きのメソッドでメソッドチェーンするのは混乱の元なので、そういう使い方を防止したい」というMatzさんの意向があるためです。

同じような議論をその昔以下の記事(のコメント欄)でしたので、よかったら参考にしてみてください。

https://gogutan.hatenablog.com/entry/2019/08/07/214450

phoenixphoenix

!をつけなければいいのでは!?と思い、記事に追加しようとしたら、、、早くも貴重なコメントを頂けて嬉しいです!

なるほど!そういった意向があるんですね 🤔
勉強になります!!ありがとうございます 🙏