What’s the difference between map and each? Let’s start with the concept of iteration:
Iteration is the process of doing something over and over.
In Ruby, iteration frequently occurs in the Array and Hash classes by looping through a list of items, manipulating them, and then returning a new version of each item.
Luckily for us, Ruby does a lot of the heavy lifting by providing us with each method and an Enumerable mixin.
The Ruby Docs tell us that “the Enumerable mixin provides collection classes with several traversal and searching methods, and with the ability to sort. The class must provide an each method, which yields successive members of the collection.”
So what does this mean exactly? If the class you want to iterate over provides an each method, you can mixin the Enumerable module giving you access to additional methods.
For our examples, we will be using Ruby’s Array class to build a pizza method that takes an array of toppings as an argument.
What we want our methods to do
- Take in an array of pizza toppings.
- Iterate through each topping, one at a time.
- Manipulate that data (do something to it).
- Return the manipulated data.
Each
The most important thing to remember about each is that it does not change the return value. It implicitly returns the original array.
This method will print:
But the return value is still:
If we want to change the return value, we have to tell it to do so.
In this version of our pizza method, we set an empty array called my_statements, which we will then explicitly return after we finish our loop. Inside our each statement loop, we manipulate each topping by interpolating it inside a string. We then push that string into our my_statements array. After we iterate over each topping in our array, we return the new my_statements array.
Our new return value:
However, if we do want to change the return value, there is a handy method called map, also known as collect. These two methods are synonyms for each other, and they implicitly return a new return value every time. Map and collect are abstractions of our each method. An abstraction is the process of taking away or removing characteristics from something to reduce it to a set of essential characteristics. Let’s take a look at a few examples.
Map & Collect
This method will print:
This method will return:
Why nil?
If you look inside our map loop, you will see that we are using puts, which always has a nil return value. What this is telling us is that our return value is indeed being changed by map. Let’s look at another example.
Here we are no longer using puts, but instead implicitly returning what is inside our block — again showing that map will give us a new return value based on the logic inside our block.
Our new return value:
Takeaway:
If you want to change the return value use map.
If you want to return the original return value use each.
It’s common to reach for each when dealing with arrays and hashes, but now that you have an understanding of map, you have another tool in your bag! Remember to be mindful of your return value. Knowing what you want to return will help you determine which method to use.