配列の便利なメソッドを使いこなそう
学習の目標
本章では、以下の内容を学習します。
- mapメソッドの基本的な使い方を理解する
- mapメソッドを使って配列の要素を変換する方法を習得する
- selectメソッドを使って条件に合う要素を抽出する方法を学ぶ
- 複数のメソッドを組み合わせて効率的に配列を操作する技術を身につける
はじめに
前章ではeachメソッドを使って配列の各要素を処理する方法を学びました。eachメソッドは汎用的でとても便利ですが、特定の目的に特化したメソッドを使うことで、コードをさらに簡潔に書くことができます。
本章では、配列操作をより効率的に行うための2つの重要なメソッド、mapメソッドとselectメソッドについて学んでいきます。これらのメソッドを使いこなせるようになると、より少ないコードでより多くのことができるようになります。
mapメソッドの基本
配列の要素を変換する
mapメソッドは、配列の各要素を変換して新しい配列を作るためのメソッドです。例えば、「すべての数値を2倍にした配列が欲しい」「すべての商品名に『特売』を付けた配列が欲しい」といった場合に便利です。
それでは、具体的な例を見ていきましょう。map.rb
というファイルを作成し、以下のコードを書いてみてください。
numbers = [1, 2, 3, 4, 5]
# mapメソッドを使って各要素を2倍にするdoubled_numbers = numbers.map do |n| n * 2end
puts doubled_numbers.inspect # [2, 4, 6, 8, 10]
このコードでは、配列numbers
の各要素を2倍にした新しい配列をdoubled_numbers
に格納しています。mapメソッドは、ブロック内で計算した結果を自動的に新しい配列に集めてくれるのです。
eachメソッドとの比較
同じ処理をeachメソッドで行うと、以下のようになります。
numbers = [1, 2, 3, 4, 5]
# eachメソッドを使った場合doubled_numbers = []numbers.each do |n| doubled_numbers << n * 2end
puts doubled_numbers.inspect # [2, 4, 6, 8, 10]
eachメソッドを使う場合は、新しい配列を事前に用意し、そこに要素を追加していく必要があります。一方、mapメソッドはこれらの作業を自動的に行ってくれるため、コードがシンプルになります。
mapメソッドの仕組み
mapメソッドの大きな特徴は、ブロック内で評価された最後の式の値を集めて新しい配列を作るという点です。つまり、mapメソッドは以下のような流れで動作します。
- 元の配列の各要素を順番にブロック変数に代入する
- ブロック内のコードを実行し、最後に評価された式の値を取得する
- その値を新しい配列の要素として追加する
- すべての要素に対して処理が終わったら、新しい配列を返す
この仕組みにより、mapメソッドは「変換」や「加工」という意図を明確にしたコードになります。
簡潔な書き方
mapメソッドも、eachメソッドと同様に波括弧{}
を使って1行で書くこともできます。
numbers = [1, 2, 3, 4, 5]
# 1行で書く場合doubled_numbers = numbers.map { |n| n * 2 }
puts doubled_numbers.inspect # [2, 4, 6, 8, 10]
処理が1行で済む簡単な変換の場合は、このように書くとさらに簡潔になります。
実用的なmapメソッドの使い方
文字列の加工
mapメソッドは数値だけでなく、様々な型のデータを変換できます。例えば、文字列の配列に対して使うこともできます。
fruits = ["りんご", "バナナ", "みかん"]
# 各要素に「特売」を付けるsale_fruits = fruits.map { |fruit| "特売 #{fruit}" }
puts sale_fruits.inspect # ["特売 りんご", "特売 バナナ", "特売 みかん"]
このコードでは、果物の名前の配列に対して、各要素の前に「特売」という文字を付けた新しい配列を作成しています。
複雑な変換
mapメソッドのブロック内では、複数行の処理を書くこともできます。例えば、価格に応じて異なる割引を適用する例を見てみましょう。
prices = [100, 300, 500, 800, 1200]
discounted_prices = prices.map do |price| if price >= 1000 price * 0.8 # 1000円以上は20%割引 elsif price >= 500 price * 0.9 # 500円以上は10%割引 else price # それ以外は割引なし endend
puts discounted_prices.inspect # [100, 300, 500, 720, 960]
このように、ブロック内で条件分岐を使うことで、より複雑な変換ルールを適用することもできます。ブロックの最後に評価される値が、新しい配列の要素となります。
selectメソッドの基本
条件に合う要素を抽出する
次に学ぶのはselectメソッドです。selectメソッドは、配列の中から条件に合う要素だけを抽出して新しい配列を作るためのメソッドです。
以下の例を見てみましょう。select.rb
というファイルを作成し、次のコードを書いてください。
numbers = [1, 2, 3, 4, 5]
# 偶数だけを選択するeven_numbers = numbers.select do |n| n.even? # nが偶数かどうかを判定end
puts even_numbers.inspect # [2, 4]
このコードでは、配列numbers
から偶数だけを抽出して新しい配列even_numbers
を作成しています。even?
メソッドは数値が偶数かどうかを判定するRubyの組み込みメソッドで、偶数の場合にtrue
を返します。
eachメソッドとの比較
同じ処理をeachメソッドで書くと、以下のようになります。
numbers = [1, 2, 3, 4, 5]
# eachメソッドを使った場合even_numbers = []numbers.each do |n| even_numbers << n if n.even?end
puts even_numbers.inspect # [2, 4]
eachメソッドを使う場合、新しい配列を用意し、条件に合う要素だけを追加する必要があります。一方、selectメソッドはこれらの作業を自動的に行ってくれるため、コードがシンプルになります。
selectメソッドの仕組み
selectメソッドの動作原理は以下のとおりです。
- 元の配列の各要素を順番にブロック変数に代入する
- ブロック内のコードを実行し、最後に評価された式が
true
かfalse
かを判定する true
の場合のみ、その要素を新しい配列に追加する- すべての要素に対して処理が終わったら、新しい配列を返す
この仕組みにより、selectメソッドは「フィルタリング」や「抽出」という意図を明確にしたコードになります。
簡潔な書き方
selectメソッドも、1行で記述することができます。
numbers = [1, 2, 3, 4, 5]
# 1行で書く場合even_numbers = numbers.select { |n| n.even? }
puts even_numbers.inspect # [2, 4]
条件式が単純な場合は、このように書くとさらに簡潔になります。
実用的なselectメソッドの使い方
複数の条件による抽出
selectメソッドでは、複数の条件を組み合わせて要素を抽出することもできます。例えば、3の倍数かつ5より大きい数を抽出する例を見てみましょう。
numbers = [3, 6, 9, 12, 15, 18, 21]
result = numbers.select do |n| n % 3 == 0 && n > 15end
puts result.inspect # [18, 21]
このコードでは、「3で割り切れる(3の倍数)」かつ「15より大きい」という2つの条件を両方満たす要素だけを抽出しています。
ハッシュからの抽出
selectメソッドはハッシュにも使うことができます。例えば、特定の条件に合うキーと値のペアだけを抽出する例を見てみましょう。
fruits_price = { apple: 100, banana: 80, orange: 120, grape: 300, melon: 500 }
# 200円以上の果物だけを抽出expensive_fruits = fruits_price.select do |fruit, price| price >= 200end
puts expensive_fruits.inspect # {:grape=>300, :melon=>500}
ハッシュに対してselectメソッドを使う場合、ブロック変数にはキーと値の2つが渡されます。このブロック内で条件を指定することで、条件に合うキーと値のペアだけを持つ新しいハッシュを作ることができます。
メソッドを組み合わせた高度な使い方
mapとselectの組み合わせ
これまで学んだmapメソッドとselectメソッドを組み合わせることで、より複雑な処理も簡潔に書くことができます。例えば、「偶数だけを抽出してから2倍にする」という処理を考えてみましょう。
numbers = [1, 2, 3, 4, 5]
# 偶数だけを抽出して2倍にするresult = numbers.select { |n| n.even? }.map { |n| n * 2 }
puts result.inspect # [4, 8]
このコードでは、まずselectメソッドで偶数のみを抽出し([2, 4])、その結果に対してmapメソッドで各要素を2倍にしています([4, 8])。
このように、Rubyではメソッドを連鎖させて(チェーンさせて)呼び出すことができます。これにより、複数の操作を1行で簡潔に記述できるのです。
処理の順序に注意
メソッドを組み合わせる際は、処理の順序に注意する必要があります。例えば、先ほどの例を逆の順序で書くとどうなるでしょうか。
numbers = [1, 2, 3, 4, 5]
# 各要素を2倍にしてから偶数だけを抽出するresult = numbers.map { |n| n * 2 }.select { |n| n.even? }
puts result.inspect # [2, 4, 6, 8, 10]
この場合、まずmapメソッドで各要素を2倍にし([2, 4, 6, 8, 10])、その結果に対してselectメソッドで偶数のみを抽出しています。しかし、2倍にすると全ての数が偶数になるため、結果は[2, 4, 6, 8, 10]となります。
このように、メソッドの呼び出し順序によって結果が大きく変わることがあるので、目的に応じて適切な順序を選ぶことが重要です。
mapメソッドとselectメソッドのまとめ
mapメソッドとselectメソッドの主な特徴と使い分けをおさらいしましょう。
mapメソッド
- 目的:配列の各要素を変換して新しい配列を作る
- 特徴:ブロック内の評価結果を集めた新しい配列を返す
- 使うタイミング:各要素に同じ変換や加工を適用したいとき
selectメソッド
- 目的:条件に合う要素だけを抽出して新しい配列を作る
- 特徴:ブロックが
true
を返す要素だけを集めた新しい配列を返す - 使うタイミング:特定の条件を満たす要素だけを取り出したいとき
まとめ
本章では、配列操作をより効率的に行うための重要なメソッドを学びました。以下の内容をマスターできたことと思います。
- mapメソッドを使って配列の各要素を変換し、新しい配列を作る方法
- selectメソッドを使って特定の条件を満たす要素だけを抽出する方法
- eachメソッドと比較した場合のmapメソッドとselectメソッドの利点
- 複数のメソッドを組み合わせて、より複雑な処理を簡潔に記述する方法
これらのメソッドを使いこなせるようになると、より少ないコードでより多くのことができるようになります。Rubyには他にも便利なメソッドがたくさんありますが、mapとselectは特に頻繁に使われる基本的なメソッドですので、ぜひ使い方を覚えておきましょう。
Starterプランでより詳しく学習
この先のコンテンツを読むにはStarterプラン以上が必要です。より詳細な解説、実践的なサンプルコード、演習問題にアクセスして学習を深めましょう。