💫
uniqとcompactを同時に使えない場合もある?
uniqメソッド
配列から重複を取り除いて、新たな配列を返すメソッドのこと
compactメソッド
配列からnilを取り除いて、新たな配列を返すメソッドのこと
同時に使えなかった状況
配列の要素によっては、同時に使えない場合があった。。。
配列に重複も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
@phoenix さん、こんにちは。
この件ですが、「どうしても」という理由がなければ
!
の付かない、ただのuniq
やcompact
を使った方がいいです。!
付きのメソッドがnilを返すのは、「!付きのメソッドでメソッドチェーンするのは混乱の元なので、そういう使い方を防止したい」というMatzさんの意向があるためです。同じような議論をその昔以下の記事(のコメント欄)でしたので、よかったら参考にしてみてください。
!をつけなければいいのでは!?と思い、記事に追加しようとしたら、、、早くも貴重なコメントを頂けて嬉しいです!
なるほど!そういった意向があるんですね 🤔
勉強になります!!ありがとうございます 🙏