I am having trouble understanding the differences between map
and each
, and where and when to use them.
I read "What does map do?" and "Ruby Iterators" but wanted some clarification.
If I have:
z = [1,2,3].map {|x| x + 1}
map
takes each element in the array z
and adds one to each element, however it does not mutate the original array unless I add !
.
On the other hand:
y = [1,2,3].each {|x| x + 1}
returns [1,2,3]
. This is confusing to me since:
names = ['danil', 'edmund']
names.each { |name| puts name + ' is a programmer' }
returns:
Danil is a programmer
Edmund is a programmer
What is exactly going on in my second example that isn't allowing each array element to be increased by 1
, while in the last example a string is being attached to everything in the array?
All credits go to Speransky Danil, whom I took these examples off of.
The map
method takes an enum
given some block, and iterates through it doing some logic. In your case the logic is x+1
. As you say it will not mutate anything unless you use !
.
each
is simply returning the array that is being called.
Let's take an example of:
names = ["bob"]
If we do:
names.each{|names| names + "somestring"}
the output is still ["bob"]
. The reason your second example is different is due to the puts
.
As an exercise try doing:
y = [1,2,3].each {|x| puts x + 1}
You will get:
2
3
4
[1,2,3]
tl;dr: I use map
if I want to change my collection, apply a transformation on it, end up with something different. I use each
if I just need to visit every element in a collection.
Key point is: you should use map
if you want to apply a transformation on an array (an enumerable in reality, but let's keep it simple at the beginning). Otherwise, if you don't need to change your array, you can simply use each
.
Note that in the code below you are not mutating the array but you are simply take advantage of the local string to print each string with a suffix.
names = ['danil', 'edmund']
names.each { |name| puts name + ' is a programmer' }
Obviously, you could do the same with map
but in this case you don't need it and you have to use an each too to print every element. The code would be
names = ['danil', 'edmund']
names.map! { |name| name + ' is a programmer' }
# or names = names.map { |name| name + ' is a programmer' }
name.each { |name| puts name }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With