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:
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.
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.
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:
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.
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.
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
.
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.
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.
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.
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 🙂