Enumerables: .each vs .map vs. .map!

Saturday, November 22, 2014

Quick Intro to Enumberables

According to Ruby-doc (my favorite reference source.......):

The Enumerable mixin provides collection classes with several traversal and searching methods, and with the ability to sort.

Wut. Basically, enumberables allow us to take elements from collections (arrays, hashes, etc) one at a time. We can do certain things to each one of them. Depending on what we do, we may have new results or the same old original results.

Let's use these three enumerators to illustrate how enumberable methods work: .each, .map, and .map!, along with an array called not_fun. Inside not_fun are three activities, strings to be exact:

> not_fun = ["washing dishes", "dieting", "doing paperwork"]
=> ["washing dishes", "dieting", "doing paperwork"]

.each

.each method allows you to go through the block of code for each element (in this case, our activity strings) of the array, but it returns the original object (the no_fun array).

> not_fun.each {|activity| activity.capitalize + " is so fun...not."}
=> ["washing dishes", "dieting", "doing paperwork"]
> not_fun
=> ["washing dishes", "dieting", "doing paperwork"]

With .each, we capitalize each activity and form a sentence. However, you will see that it returned the original array without capitalization or the rest of the sentence. The reason why is .each doesn't modify the array. Also you don't see "Washing dishes is so fun...not" because we didn't put puts in the block of code. But don't worry about that because puts, return, p, and prints are a whole different beast to mess with.

.map

.map method returns the new object with changes but it doesn't change the original array. Basically it's kind of like this kid using a protector sheet to draw over the original worksheet with a whiteboard marker.

However, in the end you can still pull the original worksheet from the protector sheet and it's as if his chubby crooked-line-drawing hands have never touched it. Or something, kind of like that.... let's see with actual Ruby.

> not_fun.map {|activity| activity.capitalize + " is so fun...not."}
=> ["Washing dishes is so fun...not.", "Dieting is so fun...not.", "Doing paperwork is so fun...not."]

Here you see that with .map, it returns a modified array where the activity is capitalized and in a complete sentence for each activity. However, if you run the array again, you will see it returned the original array without capitalization and sentence:

> not_fun
=> ["washing dishes", "dieting", "doing paperwork"]

.map!

.map! has an ! attached to it, making it a "destructive" version of .map. Destructive means it will modify and replace the original object with the changes done to each element.

> not_fun.map! {|activity| activity.capitalize + " is so fun...not."}
=> ["Washing dishes is so fun...not.", "Dieting is so fun...not.", "Doing paperwork is so fun...not."]

When you run the not_fun array, you will see it has changed into a new array:

> not_fun
=> ["Washing dishes is so fun...not.", "Dieting is so fun...not.", "Doing paperwork is so fun...not."]

...and there you have it!