Ruby Hashes in Depth
Hashes grow and change as a program runs, and Ruby gives tools for joining and rebuilding them. The beginner course covered reading and writing pairs, and this lesson goes deeper.
Joining hashes with merge
merge joins the two hashes into one. Both hashes hold an age, and the later value 31 wins.
a = {name: "Ana", age: 30}
b = {age: 31, city: "Oslo"}
p a.merge(b)Rebuilding values with transform_values
transform_values runs the block on each value and builds a new hash. The first hash keeps its old values.
prices = {pen: 2, book: 5}
doubled = prices.transform_values { |price| price * 2 }
p doubled
p pricesCounting with Hash.new(0)
Hash.new(0) starts every missing key at 0, so the counting line needs no first check. A word that never appears still reads as 0.
counts = Hash.new(0)
words = ["cat", "dog", "cat"]
words.each { |word| counts[word] += 1 }
p counts
puts counts["fish"]Walking nested hashes with dig
dig reads the city through the address key in one line. A missing path gives nil, and nil? confirms it.
user = {name: "Ana", address: {city: "Oslo", zip: "0150"}}
puts user.dig(:address, :city)
missing = user.dig(:contact, :email)
puts missing.nil?fetch raises for a missing key
fetch asks for the age key, and the hash holds no such key. The program raises a KeyError and prints nothing.
person = {name: "Ana"}
puts person.fetch(:age)Example
base = {pen: 2, book: 5}
extra = {book: 6, ruler: 3}
stock = base.merge(extra)
raised = stock.transform_values { |price| price + 1 }
p raisedKey points
- merge joins two hashes into one new hash.
- A later value wins when both hashes share a key.
- transform_values builds a new hash with changed values and the same keys.
- Hash.new(0) gives a missing key the value 0.
- dig walks nested hashes one key at a time.
- dig gives nil when a step along the path is missing.
- fetch raises an error when a key is missing.
In this example, merge joins the base and extra hashes, and the extra book price 6 wins over the base price 5. transform_values then adds 1 to every price and builds the raised hash. The p line shows the final prices.
Note
Square brackets give nil for a missing key instead of raising an error.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
The hash is counts = Hash.new(0). What does counts[:visits] give before any pair is stored?