Arrays & Hashes in Ruby
March 5th 2016
Arrays & Hashes are very powerful Ruby concepts that allow to store and structure data.
In this blogpost I will introduce you to these concepts, the differences between them, and when to apply them in your code.

Introduction
Until now, we have used variables
to store specific values that we may want to use in our program. For example, you can define a variable that holds the name of your favorite book, and works great if you have only one book to define.
favorite_book = 'Learn to program'
If however you are a big reader and you can't really choose among your favorite books, this becomes very inconvenient:
favorite_book_1 = 'Learn to program'
favorite_book_2 = 'The well grounded Rubyist'
favorite_book_3 = 'Eloquent JavaScript'
favorite_book_4 = 'HTML and CSS'
favorite_book_5 = 'JavaScript and JQuery'
Not only will you define every favorite book separately, you will also have to call and manipulate each of these books separately, which makes it a very manual, labor intensive process.
Ruby has two helpful concepts that allow you to store collections of data: Arrays & Hashes. As the example below illustrates, both concepts can link a large set of data to one single object.
Example Array: favorite_books = ['Learn to program' , 'The well grounded Rubyist' , 'Eloquent JavaScript' , 'HTML and CSS' , 'JavaScript and JQuery']
Example Hash: favorite_books = {
'The well grounded Rubyist' => 'Chris Pine' ,
'The well grounded Rubyist' => 'David A. Black' ,
'Eloquent JavaScript' => 'Marijn Haverbeke' ,
'HTML and CSS' => 'John Duckett' ,
'JavaScript and JQuery' => 'John Duckett'
}
Arrays & Hashes: Syntax and Basic Rules
Both arrays and hashes are collections of data with 'slots' that can point to a specific object. Basically each 'slot' acts like a variable by itself and allows us to group them together.
The major difference is that:
-
Arrays: have slots that are sequentially lined up in a numbered way, starting from 0 up to the last element.
You can call an element by calling it's index (the number of the slot in which the value is stored).
Example Array: favorite_books = ['Learn to program' , 'The well grounded Rubyist' , 'Eloquent JavaScript' , 'HTML and CSS' , 'JavaScript and JQuery']
- If you want to access the third element in the array, you will call it with
favorite_books[2]
. This will return value 'Eloquent Javascript'.
-
Hashes: Whereas arrays store only values and assign them to a specific (numbered) slot, hashes use key-value pairs. A 'key' can be any Ruby object, and points to a specific value (just like the index in an array would). Because hashes are not purely based on a sequential, numerical order (indexes), keys have an extra dimension to store structured data: as the example below illustrates, the book is used as a key and refers to a linked author.
Example Hash: favorite_books = {
'Learn to program' => 'Chris Pine' ,
'The well grounded Rubyist' => 'David A. Black' ,
'Eloquent JavaScript' => 'Marijn Haverbeke' ,
'HTML and CSS' => 'John Duckett' ,
'JavaScript and JQuery' => 'John Duckett'
}- If you want to know the author of 'Eloquent Javascript', you can retrieve it with
favorite_books['Eloquent Javascript']
. This will return the author 'Marijn Haverbeke'. - Important Note:Because a key is used to point to a value, it should be unique by definition.
Following links provide more information about technical implementation of Arrays and Hashes.
Use cases
We have briefly discussed the difference between arrays and hashes and how to use them in a technical way. Because of their distinct way of indexing the values they store they have different applications as well.
Let's have a look at the menu of an Italian restaurant: Giovanni, the chef is a passionate & proud Italian who aims to run his business like a pro!
Il 'Array'
Giovanni knows the menu backwards and forwards, and prepares both the orders and check based on the number of the plate (that he knows by heart). His cousin Mario made a basic app for him that uses an array
to retrieve the price of each item, by calling it by number.
In practice it looks something like this: prezzi = [8.95 , 11.50 , 14.00 , 12.50 , 13.00]
When Giovanni makes the check for a customer, he will call type in the number of the plate in Mario's array-application, and get the price of the plate back.
For example, the price of pizze quattro stagioni, number three on the menu will be called will be called by prezzi [2]
.
Mario chose to use an Array because Giovanni only needed to know the prices of his dishes, in a specific order. Because Giovanni knows the number of each dish on the menu, he can quickly retrieve the prices by using the number as an index.
Il 'Hash'
For the adding a brief description to each plate however, Mario pulled another trick: He created a 'hash' to keep the description and plate well-linked.
The tool will look something like this:
piatti = {
'Margherita' => 'tomato sauce, mozzarella di bufala, fresh basil',
'Il Forno' => 'tomato sauce, spinach-ricotta, olives, onion, mozzarella di bufala',
'Quattro Stagioni' => 'tomato sauce, prosciutto, mushrooms, artichokes, mozzarella di bufala',
'Salsiccia' => 'tomato sauce, sausage, pepperoni, mushrooms, oregano',
'Rustica' => 'sautéed broccoli, hot sausage, soppressata, extra virgin olive oil, parmigiano'
}
The textual menu has more detailed descriptions, with information that is directly related, one to the other. Therefore Mario chose to use an array for storing this information.
Sidenote: We see many ingredients coming back across dishes. Mario could improve his coding by avoiding repetition, and replace each of the ingredient by a unique code. If then, some day Giovanni needs to replace the name of an ingredient, he only needs to do this once instead of in every dish... But we'll cover this in an other blogpost some day.