マージと変換
CoddyのRubyジャーニー「ロジックとフロー」セクションの一部 — レッスン 36/56。
ハッシュを扱う際、非常によく使われる2つの操作があるため、Rubyではそれらに専用のメソッドが用意されています。
mergeは2つのハッシュを結合して新しいハッシュを作成します。両方のハッシュに同じキーが存在する場合、右側の値が優先されます。
defaults = { color: "red", size: "M" }
custom = { size: "L" }
settings = defaults.merge(custom)
puts settings.inspect # {color: "red", size: "L"}元のオブジェクトはどちらも変更されず、merge は新しいハッシュを返します。
transform_values は、同じキーを保持したまま、各値をブロックに渡して変換した新しいハッシュを構築します:
prices = { apple: 1, bread: 3 }
with_tax = prices.transform_values { |p| p * 1.2 }
puts with_tax.inspect # {apple: 1.2, bread: 3.6}そして、transform_keysはキーに対して同じことを行います。これは文字列をシンボルに変換したり、大文字・小文字を正規化したりする際に便利です:
{ "a" => 1, "B" => 2 }.transform_keys(&:upcase)
# {"A"=>1, "B"=>2}チャレンジ
中級2つのカートのハッシュ、monday と tuesday が与えられています。それぞれ、文字列のアイテム名を整数の数量にマッピングしています。ショップは、正規化された2日間の合計を求めています。
以下の手順で1つの最終的なハッシュを作成してください:
- 2つのハッシュをブロック付きで
mergeし、両方に存在するキーの数量が(上書きされるのではなく)合算されるようにします - 結果に対して
transform_keys(&:to_sym)を行い、キーをシンボルに変換します transform_valuesを使用して10%の一括割引を適用します。すべての数量は整数演算を使用して(qty * 9 / 10)になります
最終的なハッシュを inspect で出力してください。
デフォルトのデータの場合、出力は以下のようになります:
{:apples=>9, :bread=>4, :milk=>5, :cheese=>1}(Apples: 5 + 5 = 10、その後 9。Bread: 3 + 2 = 5、その後 4。Milk: 月曜日のみ 6 → 5。Cheese: 火曜日のみ 2 → 1。)
チートシート
merge は2つのハッシュを結合します。キーが衝突した場合は、右側の値が優先されます:
defaults = { color: "red", size: "M" }
custom = { size: "L" }
settings = defaults.merge(custom)
# {color: "red", size: "L"}重複するキーを手動で処理するには、merge にブロックを渡します:
a.merge(b) { |key, old_val, new_val| old_val + new_val }transform_values は、各値をブロックに渡して処理した新しいハッシュを返します:
prices = { apple: 1, bread: 3 }
prices.transform_values { |p| p * 1.2 }
# {apple: 1.2, bread: 3.6}transform_keys はキーに対して同じことを行います:
{ "a" => 1 }.transform_keys(&:upcase) # {"A"=>1}
{ "a" => 1 }.transform_keys(&:to_sym) # {a: 1}自分で試してみよう
monday = { "apples" => 5, "bread" => 3, "milk" => 6 }
tuesday = { "apples" => 5, "bread" => 2, "cheese" => 2 }
# TODO: 重複するキーを合計するために merge-with-block を使用し、次にキーをシンボル化し、
# その後すべての値に * 9 / 10 を適用してから、内容を確認する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。