Merging and Transforming
Part of the Logic & Flow section of Coddy's Ruby journey. Lesson 36 of 56.
Two operations come up so often when working with hashes that Ruby gives them their own methods.
merge combines two hashes into a new one. When both have the same key, the right-hand value wins:
defaults = { color: "red", size: "M" }
custom = { size: "L" }
settings = defaults.merge(custom)
puts settings.inspect # {color: "red", size: "L"}Neither original is modified, merge returns a new hash.
transform_values builds a new hash with the same keys but each value passed through a block:
prices = { apple: 1, bread: 3 }
with_tax = prices.transform_values { |p| p * 1.2 }
puts with_tax.inspect # {apple: 1.2, bread: 3.6}And transform_keys does the same for keys, useful when converting strings to symbols, or normalizing case:
{ "a" => 1, "B" => 2 }.transform_keys(&:upcase)
# {"A"=>1, "B"=>2}Challenge
MediumTwo cart hashes are given: monday and tuesday, each maps a string item name to an integer quantity. The shop wants a normalized two-day total.
Produce one final hash by:
merge-ing the two hashes with a block so that keys present in both have their quantities summed (not overwritten)transform_keys(&:to_sym)on the result, so keys become symbolstransform_valuesto apply a 10% bulk discount: every quantity becomes(qty * 9 / 10)using integer math
Print the final hash with inspect.
For the default data, the output is:
{:apples=>9, :bread=>4, :milk=>5, :cheese=>1}(Apples: 5 + 5 = 10, then 9. Bread: 3 + 2 = 5, then 4. Milk: 6 only on Monday → 5. Cheese: 2 only on Tuesday → 1.)
Try it yourself
monday = { "apples" => 5, "bread" => 3, "milk" => 6 }
tuesday = { "apples" => 5, "bread" => 2, "cheese" => 2 }
# TODO: merge-with-block to sum overlapping keys, then symbolize keys,
# then apply * 9 / 10 to every value, then inspect
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Strings In Depth
String Methods OverviewString InterpolationIterating Over StringsSplit and JoinRecap - String Weaver4Blocks, Procs & Lambdas
What is a Block?do..end vs BracesThe yield KeywordBlock ParametersProcs and LambdasRecap - Custom Iterator7Hashes Part 2
Hash.new with DefaultsIterating HashesNested HashesMerging and TransformingRecap - Frequency Counter10Project - Student Records
Project OverviewAdd Student5Enumerable Powerhouse
Select and RejectChaining MapReduce / Injectcount, all?, any?, none?group_by and partitionsort_by, min_by, max_byRecap - Data Pipeline8Advanced Decision Making
Case with Classes & RegexMulti-value whenTernary OperatorInline if / unlessRecap - Grade ClassifierPractice on your own: Online Ruby compiler