Dive into the intricacies of Ruby on Rails by learning about collections in this tutorial, covering topics such as arrays, hashes, enumerators and common iterators.
This exercise is excerpted from Noble Desktop’s past web development training materials. Noble Desktop now teaches JavaScript and the MERN Stack in our Full Stack Development Certificate. To learn current skills in web development, check out our coding bootcamps in NYC and live online.
Note: These materials are provided to give prospective students a sense of how we structure our class exercises and supplementary materials. During the course, you will get access to the accompanying class files, live instructor demonstrations, and hands-on instruction.
Topics covered in this Ruby on Rails tutorial:
Arrays: the simplest collections, Hashes, Enumerators, Common iterators
Exercise Overview
In this exercise, we will keep working with Ruby in Terminal. We will be focusing on collections, which are simply groups of variables. We will learn more about arrays and then explore the exciting topics of hashes, iterators, and enumerators.
Getting Started
Open Terminal.
-
Type the following to initialize Interactive Ruby (IRB):
irb
Arrays: The Simplest Collections
This exercise is about collections, and the simplest kind of collection in Ruby is an array. Arrays are declared with two square brackets.
-
Type the following:
bird_types = []
Terminal should reply with two brackets:
[]
because this array has not yet been populated with any values. -
We can create an array and at the same time populate it with values (separated by commas). Type the following:
bird_types = ["Robin", "Finch", "Dove"]
In response, Terminal will print with the contents of the array in brackets, like this:
["Robin", "Finch", "Dove"]
.In this array we just created, we populated the array with strings (text variables), but an array can contain any type of variable and any combination of strings, integers, float values, and so on. (Arrays can even contain other arrays!)
-
What if you create an array and later on you realize that you’ve forgotten an item? It’s easy to append additional items to existing arrays by using an operator that looks like a double-arrow
<<
pointing toward the array name. Let’s create an array and try adding an item to the array after it’s created. Type the following:bird_types << "Woodpecker"
Terminal should reply with the newly updated contents of the array:
["Robin", "Finch", "Dove", "Woodpecker"]
. With the<<
operator we were able to append an item to our array after it was created. -
Do you remember how we were able to access substring values of strings in a previous exercise? We can access array positions in the exact same way, by using an integer position between brackets. (Remember, Ruby starts counting with zero!) Let’s see how it works by typing:
bird_types[0]
Terminal should reply
"Robin"
, which occupies position 0 in our array of birds. -
Try accessing another array position by typing:
bird_types[2]
Terminal should reply
"Dove"
, which occupies position 2 in our array of birds. -
We can use this same syntax to replace elements within an array. Let’s take a quick look at our array of birds again by typing:
bird_types
Terminal should reply
["Robin", "Finch", "Dove"]
-
What if we wanted to modify the array by replacing one of these birds with another? Type the following:
bird_types[1] = "Oriole" bird_types
Terminal should now list the contents of the array as
["Robin", "Oriole", "Dove", "Woodpecker"]
. We have replaced position 1 in this array, changing Finch to Oriole. -
We can also use a range to make multiple replacements. Type the following:
bird_types[1..2] = ["Macaw", "Eagle"] bird_types
Because Terminal lists the contents of the array as
["Robin", "Macaw", "Eagle", "Woodpecker"]
, we can see that we’ve replaced position 1 and position 2 in our array by using the range[1..2]
.
Hashes
Hashes are similar to arrays, and they’re very widely used in Rails. With arrays, we used an integer to reference an individual element, but in a hash, an element can be referenced by any variable type. Although you are able to use any variable type, symbols are most frequently used when dealing with hashes, so that’s what we’ll explore now.
-
Hashes are defined with two curly braces. Type the following to define a hash:
town_council = {}
We have just created a new empty hash, and Terminal should reply
{}
. -
Who should we put on our town council? Type the following command as one line in Terminal. Don’t hit Return until you’ve typed the final curly brace.
town_council = { :president => "Marcus Aurelius", :vice_president => "Eleanor Roosevelt", :treasurer => "Cleopatra" }
Great, we’ve populated our town council hash!
NOTE: Hash elements are called keys and values.
-
Keys are the symbols such as
:president
, which are internal to your application. -
Values are the information, in this case the names such as
"Marcus Aurelius"
, which will be visible to the end user.
-
Keys are the symbols such as
-
The syntax that we used to populate our town council hash is a common but outdated syntax. You may see it in sample code you find online, so it’s important to recognize it, but there is a newer, simpler syntax. Type the following (again, as one single-line command) to make a hash of the Beatles:
beatles = { guitar: "John Lennon", bass: "Paul McCartney", lead_guitar: "George Harrison", drums: "Ringo Starr" }
Notice that the colon comes after the symbol, not before. This newer syntax is preferred because it’s shorter, easier to write, and easier to read. The two syntaxes do the exact same thing, of course, which you can confirm by looking at the similarity of Terminal’s responses that it printed after populating the town_council hash and the beatles hash.
-
Hashes are great because we are now able to call the keys as symbols to get their values. Type the following:
town_council[:president]
Terminal should reply
"Marcus Aurelius"
, which is the value associated with the key and symbol:president
. -
Let’s try using a different symbol with our other hash. Type the following:
beatles[:drums]
Terminal should reply
"Ringo Starr"
, and hopefully you’re getting the hang of using symbols as keys to access information in a hash! -
These values aren’t permanent, and they can be updated using the same syntax. Try typing the following to add a position to our town council:
town_council[:secretary] = "Mark Twain" town_council
Terminal should list the contents of the hash, with Mark Twain’s new secretary position included at the end.
-
We can use this syntax to replace values, too. Type the following:
beatles[:bass] = "Impostor Paul" beatles
Now when we call beatles, we can see that the bass player Paul was replaced with an
"Impostor Paul"
. You can see how simple it is to replace values in a hash, and overall, how flexible hashes can be.
Enumerators
Enumerators are Ruby objects that iterate (loop) over themselves. Let’s see how they work.
-
Type the following:
birds = bird_types.each
Terminal should return the following, which is called the enumerator:
#<Enumerator: ...>
-
Type the following:
birds.next
Terminal should return the first value,
"Robin"
. -
Do it two more times (remember, hit the Up Arrow to bring up the last command you typed!):
birds.next birds.next
Terminal should return
"Oriole"
and then"Dove"
. This is just a brief look at the way enumerators work, and you’ll later find that enumerators can be helpful when you want to step through more than one collection at the same time.
Common Iterators
Iterators are methods that step through members of a collection and perform an action with each one of them individually. There are many, many iterators in the world of Ruby. Let’s first look at one of the most commonly used ones, the map
iterator. The map
iterator steps through every instance of a collection and turns it into a whole new array. Let’s look back at our Beatles hash.
-
What if we wanted to get an array of just one element—for example, just the musicians’ names? Let’s use an iterator to create that array, and to keep things exciting, let’s make the names uppercase, too! Type the following:
names = beatles.map { |beatle| beatle[1].upcase }
Terminal should print a new array of all the names of the Beatles, in all caps! This is what the
map
iterator does: it allows you to take an existing collection, apply some sort of transformation to that collection, and get a whole new array back. Here’s a breakdown of what we just typed:-
|beatle|
is a variable which receives an individual item from the Beatles array (which contains the name of a Beatle). -
beatle[1]
calls the item at position 1 of the hash, which will be the name of each Beatle. This string is then changed by theupcase
method which simply turns the text of each string to UPPERCASE.
-
-
Let’s remove two band members. Type the following as one line of code:
guitarists = beatles.map { |beatle| beatle[1] }.reject { |beatle| beatle == "Impostor Paul" or beatle == "Ringo Starr" }
Terminal should reply
["John Lennon", "George Harrison"]
because we have chained thereject
method onto the code block with a period, telling it to reject Impostor Paul and Ringo Starr. -
Let’s look at another example involving iterators. Create an array of lucky numbers by typing the following:
lucky_numbers = [1, 3, 7, 11, 21, 42]
-
What if we want to sort these numbers and just look at the ones that are less than twenty? Type the following:
lucky_numbers.find { |lucky_number| lucky_number < 20 }
Terminal should print
1
, demonstrating that thefind
method only gives us the first result that has been evaluated as true. What if we wanted to get every true result? -
Try typing the following:
lucky_numbers.find_all { |lucky_number| lucky_number < 20 }
Terminal should reply:
[1, 3, 7, 11]
, all of the lucky numbers less than twenty, so we can see that thefind_all
method is more powerful than thefind
method.We will be seeing more examples of all of these elements in action in the following exercises, so you’ll have plenty of time to get more familiar with them as we move into working with Rails. In Rails, we will be using pretty much all the same control structures and variable types as we’ve been playing around with in Interactive Ruby in Terminal.
Type
quit
to exit Interactive Ruby.