- Read Tutorial
- Watch Guide Video
In this guide we are going to walk through on how to build a nested iterator with a practical example, namely looping over a nested Hash
in Ruby.
Before we move on, I'd like to warn you that you have to be careful while working with nested iterators because they can cause performance issues if poorly implemented. If you are working on a collection within another collection, you will go through all the elements in the nested collection when an element of the parent collection is called. This means you will go through a large number of iterations that can potentially slow your program down by quite a bit. Sometimes, the program may even crash if you have to iterate through thousands of elements across multiple collections. So be careful while using these nested iterators.
Nested Iterator Code Example
For our code example we are going to iterate over a hash
data set. We will learn about hashes
in-depth in future lessons, but for now, just know that hashes are a key value based data structure. Here is a basic nested hash:
teams = { "Houston Astros" => { "first base" => "AJ Reed", "second base" => "Jose Altuve", "shortstop" => "Carlos Correa" }, "Texas Rangers" => { "first base" => "Prince Fielder", "second base" => "R. Odor", "shortstop" => "Elvis Andrus" } }
This is a nested key-value pair structure where we have a collection called teams
. There are two teams inside this collection, namely, the Houston Astros
and Texas Rangers
. Inside each of these teams, there are positions and players.
Our program is going to go into the teams
collection and will iterate over individual positions in each team.
If you use the regular each loop like this:
teams.each do |team| p team end
your output will be:
If you notice, this code prints out all the elements inside each of the two teams. This is great if you just want to see what's inside each element, but if you want to do something with each of the nested elements, then this won't help.
To access the individual elements, we not only have to iterate through the collection teams
, but also through each of the teams present inside this collection. To do that let's update the code like below:
teams.each do |team, players| puts team players.each do |position, player| p "#{player} starts at #{position}" end end
In this code, we have two iterator variables for our parent collection, which are: team
and players
. It's setup this way because we have a collection nested inside another one. In the nested iterator loop, we iterate through the individual team and print out the position and the player. If you see, the nested iterator also has two variables because we have this information in our players
block variable. devCamp Note: block variables can be collections as well as single values. When you run into this scenario it's standard to give a plural name for the block variable, like I did for players
.
If you run this code, this is your output:
The name of the team gets printed first, and is followed by the names of position and player inside each team. Essentially, this code iterated through the teams
collection, and for every item in the teams
collection, it displays the elements present in it.
So, this is a practical way of how you can use nested iterators in Ruby to loop through a hash data structure.