What is a Ruby hash?
A hash is a data structure used to store data in the form of UNIQUE key-value pairs. Unlike arrays, there are no numerical indexes, you access the hash values with keys.
Examples include:
- A list of country names & their corresponding country codes (like ES ⇾ Spain)
- A dictionary, where every word has a list of possible definitions
- A domain name & it’s IP address
Using a hash in your Ruby programs can speed up your code when used in the right situation.
In other words:
You have data that is (or can be transformed into) a dictionary-like format, where data can be grouped by keys & associated values.
How to Create a Hash
Ok.
We get the general idea of what a hash is, but how do you create one?
Like this:
{}
That’s an empty hash!
A hash with three key/value pairs looks like this:
{ a: 1, b: 2, c: 3 }
Where a
is a key, and 1
is the corresponding value for that key. Notice that the key-value pairs are separated by commas.
Now:
Let’s look at how you can use hashes in your Ruby projects with common hash methods.
Storing Values in a Ruby Hash
You can create a hash with a set of initial values, as we have already seen.
Here’s another example:
fruits = { coconut: 1, apple: 2, banana: 3 }
Another option is to add new values into an existing hash.
Like this:
fruits[:orange] = 4
This is :orange
as the hash key, and 4
as its corresponding value.
Why is the colon before the word
:orange
when we access a value & after the wordorange:
when we create a hash? It’s a nicer syntax that allows you to create hashes without the hash-rocket (=>
) symbol, which is a valid, but older way to do it.
Values can be any Ruby object.
Including:
- Strings
- Integers & Floats
- Arrays
Keys can also be anything, but symbols (like :banana
) & strings are the most common type of keys you’ll find.
Remember that…
Keys are unique, we can only have one :orange
key, or one :apple
key.
When you add the same key twice you change its value.
How to Access Values From a Hash
You access a hash by key.
If you need to access the values directly, then a hash may not be the right structure for your data.
Example:
fruits[:orange] # 4
This is the whole point of hashes, to quickly look up an item by its key.
If a key doesn’t exist, you’ll get nil
.
fruits[:peach] # nil
As an alternative, you can use the fetch
method, which allows you to provide a default value.
Example:
fruits.fetch(:peach, 0)
If you use fetch
without a default value (the 2nd argument), Ruby will raise a KeyError
exception.
That’s helpful because you’ll know what key is missing.
How to Merge Two Ruby Hashes
You can take two hashes & merge them together into a new hash.
What method does this?
Well, it’s not hard to guess this one. The method’s name is merge
.
Here’s how to use it:
defaults = { a: 1, b: 2, c: 3 } preferences = { c: 4 } defaults.merge!(preferences) # {:a=>1, :b=>2, :c=>4}
Notice that because keys are unique, newer values overwrite older values.
You could use this fact for interesting solutions, like creating a “defaults” hash that users can override by passing their own hash.
If you need more control over how keys are merged you can pass a block.
Like this:
defaults.merge!(preferences) { |key, old, new| [old, new].max }
Where old
are the values coming from defaults
, and new
are the values coming from preferences
.
Multiple Values For One Key
In a dictionary…
Words are unique, but they can have multiple values (definitions) associated with them.
You can do this in Ruby!
Example:
dictionary = { opportunity: [ "a set of circumstances that makes it possible to do something", "a situation or condition favorable for attainment of a goal" ], creativity: [ "the use of imagination or original ideas to create something new", "the ability to create", "the process where new ideas emerge from combining existing ideas in new ways" ] } dictionary[:creativity][1]
Where dictionary[:creativity]
gives you an array & [1]
gives you the 2nd element from that array.
In other words:
The key is a symbol & the values are arrays. When you access the hash you get an array back which you access normally, like any other array.
How to Sort a Hash
You can sort arrays. But did you know that you can also sort hashes?
When you sort
a hash, it’s sorted by key.
Example:
{ b: 1, a: 2 }.sort # [[:a, 2], [:b, 1]]
But you can also sort them by value:
{ c: 3, b: 1, a: 2 }.sort_by(&:last)
You’ll notice that what you get from sorting a hash is not another hash…
It’s an array!
But you can convert this array back into a hash, using the to_h
method.
Get All Keys & Values From a Hash
If you want a list of all the hash keys, good news, there is a method for that!
Here it is:
{ apple: 1, banana: 2 }.keys # [:apple, :banana]
There’s also a method which gives you an array containing the values:
{ apple: 1, banana: 2 }.values # [1, 2]
If you want to know if a key exists in a hash, instead of getting an array of them, use the key?
method.
This method returns a true
or false
value.
Summary
You’ve learned about Ruby hashes, a helpful data structure which is composed of key-value pairs. You also learned how to access a hash by key, and how to store new data in a hash.
Now open up irb (or pry) & start playing with hashes!
Thanks for reading 🙂