はじめに
こんにちは。ProgateでRubyを勉強したのち、「ゼロからわかるRuby超入門」でさらに学習を進めています。
この本で uniq メソッドについて学んだ際、配列の中の重複要素を除外する機能が紹介されていましたが、実はそれ以外にも興味深い機能があることに気づきました。今回は、その意外な機能について共有します。
Rubyを勉強し始めたばかりなので、Rubyに詳しい方にとっては当たり前のことかもしれませんが、この記事はRuby初心者向けということでお手柔らかにお願いします。
環境:Ruby 3.3.5
uniqとは
uniq
は配列から重複した要素を取り除いた新しい配列を返します。
[1,1,1].uniq
# [1]
[1,3,2,2,3].uniq
# [1,3,2]
ほかにもuniq!
といった重複の削除を破壊的に行うコマンドもありますが、本題ではないので触れないでおきます
uniqのもう一つの機能とは?
では以下のコードを見てどういう結果が出力されるか確認しましょう。
皆さんも一緒に考えてみてください
p [1, 3, 2, "2", "3"].uniq { |n| n.to_s }
このコードでは、|n| n.to_s という部分が、各要素を文字列に変換しています。
さて、どんな結果が返ってくると思いますか?
答え
p [1, 3, 2, "2", "3"].uniq { |n| n.to_s }
# [1, 3, 2]
えっ!? 文字列ではなく元の数値が出力されています。
私はこれを["1", "3", "2"]
と予想していましたが、なぜこのような結果になったのでしょうか?
実は、これには uniq の特別な性質が関係しています。
uniq の重要な性質
uniq
は、ブロック内で評価された結果に基づいて重複を除外しますが、最終的に元の要素が出力されるという性質を持っています。
具体的には、[1, 3, 2, "2", "3"] という配列に対して、|n| n.to_s
で全ての要素が文字列に変換されるため、結果として ["1", "3", "2", "2", "3"] となります。
この時、"2"
と "3"
が重複しているので削除され、最終的に ["1", "3", "2"] という形になります。
ただし、実際に返される配列には、元の要素がそのまま返るため、結果は [1, 3, 2] になるのです。
もう一つ例を見てみましょう。
p ["1", "3", "2", 2, 3].uniq { |n| n.to_s }
# ["1", "3", "2"]
これも同様に、|n| n.to_s
によってすべての要素が文字列として扱われ、結果的に重複する要素が除外されます。
最終的な配列の要素は、元の配列に含まれていた ["1", "3", "2"] となります。
まとめ
uniq
メソッドは単に重複を除去するだけでなく、ブロックを用いて処理した結果に基づいて重複を除去し、元の要素を保持したまま返すという興味深い機能を持っています。
わたしもRuby初心者なので、Rubyをさらに深く理解するためにも、このような細かい挙動にも注目して学習を進めていきましょう!