Ruby ハッシュの繰り返し:each・map・select の使い方
ハッシュのキーと値を繰り返し処理するには each・map・select などを使います。配列とほぼ同じメソッドが使えます。
早わかりまとめ
| メソッド | 戻り値 | 向いている用途 |
|---|---|---|
each |
self | キーと値を繰り返し処理する |
map / collect |
配列 | 変換した配列を作る |
select / filter |
ハッシュ | 条件に合うペアを取り出す |
reject |
ハッシュ | 条件に合わないペアを取り出す |
transform_values |
ハッシュ | 値だけ変換したハッシュを作る |
transform_keys |
ハッシュ | キーだけ変換したハッシュを作る |
any? / all? |
boolean | 条件確認 |
to_a |
配列 | [[key, value], ...] に変換 |
each:キーと値を繰り返す
prices = { apple: 100, banana: 80, cherry: 200 }
prices.each do |key, value|
puts "#{key}: #{value}円"
end
# apple: 100円
# banana: 80円
# cherry: 200円
each_with_object で別のオブジェクトに集めることもできます。
# 値を2倍にした新しいハッシュを作る doubled = prices.each_with_object({}) do |(key, value), hash| hash[key] = value * 2 end p doubled # { apple: 200, banana: 160, cherry: 400 }
select / reject:条件でペアを絞り込む
prices = { apple: 100, banana: 80, cherry: 200, grape: 300 }
# 100円以上のもの
expensive = prices.select { |_key, value| value >= 100 }
p expensive # { apple: 100, cherry: 200, grape: 300 }
# 100円未満のもの
cheap = prices.reject { |_key, value| value >= 100 }
p cheap # { banana: 80 }
select はハッシュを返す点が配列の select と同じ動作です。
transform_values:値だけ変換する
prices = { apple: 100, banana: 80, cherry: 200 }
# 税込み価格に変換
with_tax = prices.transform_values { |price| (price * 1.1).round }
p with_tax # { apple: 110, banana: 88, cherry: 220 }
transform_values! で元のハッシュを書き換えることもできます。
transform_keys:キーだけ変換する
snake = { first_name: 'Alice', last_name: 'Smith' }
# キーを文字列に変換
stringified = snake.transform_keys(&:to_s)
p stringified # { "first_name" => "Alice", "last_name" => "Smith" }
# キャメルケースに変換
camel = snake.transform_keys do |key|
key.to_s.gsub(/_([a-z])/) { $1.upcase }.to_sym
end
p camel # { firstName: 'Alice', lastName: 'Smith' }
map:配列に変換する
ハッシュに対して map を使うと配列を返します。
prices = { apple: 100, banana: 80 }
labels = prices.map { |key, value| "#{key}: #{value}円" }
p labels # ["apple: 100円", "banana: 80円"]
map の結果をハッシュに戻すには to_h を使います。
with_tax = prices.map { |key, value| [key, (value * 1.1).round] }.to_h
p with_tax # { apple: 110, banana: 88 }
any? / all?:条件確認
prices = { apple: 100, banana: 80, cherry: 200 }
p prices.any? { |_key, value| value >= 200 } # true
p prices.all? { |_key, value| value >= 50 } # true
p prices.none? { |_key, value| value > 500 } # true
to_a:配列に変換して使う
prices = { apple: 100, banana: 80 }
p prices.to_a
# [[:apple, 100], [:banana, 80]]
# ソートも配列に変換してから行う
sorted = prices.sort_by { |_key, value| value }
p sorted # [[:banana, 80], [:apple, 100]]
まとめ
| したいこと | 使うもの |
|---|---|
| キーと値を繰り返す | each |
| 値だけ変換したハッシュを作る | transform_values |
| キーだけ変換したハッシュを作る | transform_keys |
| 条件に合うペアを絞り込む | select / reject |
| 配列に変換する | map / to_a |
| 条件確認 | any? / all? / none? |
Ruby の繰り返し処理全般は「Ruby の繰り返し処理:each・times・map の使い分け」を参照してください。