Each, Map, Collect and Select

Lawrence Hon
The Wonderful World of Code
4 min readMay 27, 2018

Like most people who begin learning anything complex I started my journey into Ruby by making sure I understood the basics. The each enumerable was my first foray into quickly looping through an array or hash. It is a powerful little four letter word that saved me the trouble of creating and incrementing a counter variable.

As beginner Rubyists we probably first learned each then map , collect , and select afterwards. If you were anything like me then you may be slightly confused by the differences between them. Before we dive into map , collect and select it’s worth understanding the humble each .

Photo by Ridham Nagralawala on Unsplash

Each

The each method is a powerful statement that when called upon can iterate over each element and perform some sort of function we’d like. The key with each, however (or any enumerable really), is what it returns (i.e., what does the program give us back when the enumerable finishes doing its thing separate from what we write in the block?).

Let’s say we have an array = [1, 2, 3, 4] and we want to to multiply each of those numbers by 10.

array = [1, 2, 3, 4]array.each do |array_element|
array_element * 10
end

>> [1, 2, 3, 4]

So we’ve created an array with the integers 1, 2, 3, 4 and used each to iterate through each element and multiply it by 10. The each statement went to 1 and multiplied it by 10. Then it went back in and did the same for 2 and then 3 etc.

But wait, what happened? We received a return value of >> [1, 2, 3, 4] . We wanted >> [10, 20, 30, 40]. It turns out each will always return back the original array. It does not change the array in any way. We could replace array_element * 10 with puts "Please, for the love of everything good in this world do not return the original array!!! Return me instead" and we would still get the original array returned back once each has finished iterating through the length of the array. Note, the statement would still be printed out, however, the return value is still the original array.

Certainly there are ways around this. We can simply just create another array and push or shovel the product of it as we iterate over it and then explicitly call the new array…

array = [1, 2, 3, 4]new_awesome_array = []array.each do |array_element|
new_awesome_array << array_element * 10
end
new_awesome_array>> [10, 20, 30, 40]

While that works just fine, we did have to do some extra work in creating a new_awesome_array and then shovel the product into it and call it to have it returned. That’s a lot of work just to get an array of numbers multiplied by ten. Thankfully Ruby has an alternative…

Photo by rawpixel on Unsplash

Map / Collect

Ok so the title of this article is slightly misleading. It turns out map and collect are the exact same. Yep, they do the same thing! I’ll stick with using map. Let’s see why map is a better alternative to each if we wanted a new array of numbers multiplied by 10.

array = [1, 2, 3, 4]array.map do |array_element|
array_element * 10
end
>> [10, 20, 30, 40]

It looks like map will iterate through each element, perform the block (i.e., array_element * 10) passed in and return a new array composed of those values. The advantage of map over each in this scenario is that we do not have to create a new array, push values into said array and return it explicitly. Rather, map will do that work for us!

Photo by Patrick Fore on Unsplash

Select

Perfect! So we have our array of numbers multiplied by 10. Now let’s say we only wanted one of those numbers, we don’t care about the rest. How do we find that? Well we could use our trusty each enumerable, create a new array, go through each element, return the element if it’s the one we are looking for or move on if it isn’t. Or we could use select which will go through the elements and only return the elements we want. Let’s see how that looks in code if we wanted to return only 20.

array = [10, 20, 30, 40]array.select do |array_element|
array_element == 20
end
>> [20]

As our return value shows select will go through each element and perform the block. If the block is true then the element will be selected, if it is false, it will be ignored.

So there you go! Now you know the differences between each, map / collect and select !

Additional Notes

Some important things to note

  • map returns an array of the same size as the original
  • select can return an array of a different size

TL;DR

  • Use map when you want to do some stuff to some other stuff and want the result of that back
  • Use select when you only want certain stuff back from the original

--

--