Working with Hashes

Dictionaries

Hashes, or Hash objects, are another useful and widely used object that can be used to store other objects.

Unlike arrays that are mere lists, Hash objects are like dictionaries.

We can use them to look one thing up through another thing. We can look a value up from a hash using a key, or retrieve the value associated with the key.

Imagine a real dictionary that translates from English to German. When we look up the English word “hello,” we find the German “hallo”. When we look up “one,” we find “eins,” and so on. The authors of this dictionary have assigned a German word (value) to an English word (key).

English Keys and German Values

Key Value
hello hallo
one eins

Hashes work much like this.

Remember: A hash assigns values to keys so that values can be looked up by their key.

We also refer to a value assigned to a key as a key/value pair. A hash can have as many key/value pairs as we like.

Creating a hash

In Ruby, we can create a hash by assigning a key to a value by separating them with =>, separating these key/value pairs with commas, and enclosing the whole thing with curly braces.

This is how it looks:

Press + to interact
{ "one" => "eins", "two" => "zwei", "three" => "drei" }

This defines a hash that contains three key/value pairs, meaning that we can look up three values (the strings "eins", "zwei", and "drei") using three different keys (the strings "one", "two", and "three").

Also, the Ruby community has come up with the name hash rocket for the bit of syntax, =>, which separates a key from a value.

Remember: A hash is created by listing key/value pairs that are separated by hash rockets and enclosed with curly braces.

Looking a value up

How do we actually look up the value associated with the key "one"?

Just like with arrays, we use square brackets. Instead of passing a number indicating the position, though, we now pass the key, like so:

Press + to interact
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
puts dictionary["one"]

Notice that we use a variable name on the second line to refer to the hash defined on the first line.

In this example, dictionary is a hash defined on the first line. The ["one"] looks up the value associated with the key "one", which is "eins". This value is passed to puts, which outputs it to the screen.

Setting a value against a key

Also, just like with arrays, there’s a way to set key/value pairs on an existing hash:

Press + to interact
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
dictionary["zero"] = "null"
puts dictionary["zero"]

This prints out null.

We could also overwrite existing key/values in the same way. For example, this sets the word "uno" to the key "one". This overwrites the existing pair with the value "eins":

Press + to interact
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
dictionary["one"] = "uno"
puts dictionary["one"]

This now outputs uno.

Any kind of object

We can use any kind of object as a key, and we can store any kind of object as a value. These are all valid hashes, for example:

Press + to interact
{ 1 => "eins", 2 => "zwei", 3 => "drei" }
{ :one => "eins", :two => "zwei", :three => "drei" }
{ "weights" => ["pound", "kilogram"], "lengths" => ["meter", "mile"] }
{ :de => { :one => "eins", :two => "zwei", :three => "drei" } }

The first example uses numbers as keys, while the second uses symbols, which is quite common in Ruby.

In the third example, notice the use of arrays as values in hashes. If we look the "weights" key up, we get an array back.

The last line is similar to what Rails uses to translate strings to different languages. It’s also an example of a nested hash. There’s another hash associated (stored) as a value for the :de key (representing the German language). This other hash now has three key/value pairs. So, a Rails programmer could look up how to translate “one” to German and get “eins” back.

Hashes can use any kind of object as keys and values.

Missing values

What happens if we try to look up a key that doesn’t exist?

Again, just as with arrays, we get back nil, meaning nothing:

Press + to interact
dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }
puts dictionary["four"]

Note: There’s one space inside the curly braces on both sides, around the hash rocket, =>, and after each comma.