How to understand Ruby.each and .map

I am having trouble understanding the differences between map and each and where and when to use them.

I read β€œ What does the map do? ” And β€œ Ruby Iterators ” but wanted to clarify.

If I have:

  z = [1,2,3].map {|x| x + 1} 

map takes every element in the z array and adds it 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 bothers me because:

 names = ['danil', 'edmund'] names.each { |name| puts name + ' is a programmer' } 

returns:

 Danil is a programmer Edmund is a programmer 

What happens in my second example, which does not allow to increase each element of the array by 1 , and in the last example, the string is attached to the entire array?

All loans go to Speransky Danil, from whom I took these examples.

+5
source share
5 answers

The map method takes the enum given block and iterates through some logic. In your case, the logic is x+1 . As you say, it will not change anything if you do not use ! .

each simply returns the array that is being called.

Take an example:

 names = ["bob"] 

If we do this:

 names.each{|names| names + "somestring"} 

the output is still ["bob"] . The reason your second example is different is due to puts .

As an exercise, try to do:

 y = [1,2,3].each {|x| puts x + 1} 

You'll get:

 2 3 4 [1,2,3] 
+3
source

tl; dr: I use map if I want to change my collection, apply a transformation to it, eventually with something else. I use each if I just need to visit every item in the collection.

Key point: you have to use map if you want to apply the transformation in an array (actually enumerable, but let it be simple at the beginning). Otherwise, if you do not need to change your array, you can simply use each .

Note that in the code below, you are not mutating the array, but just using a local line to print each line with a suffix.

 names = ['danil', 'edmund'] names.each { |name| puts name + ' is a programmer' } 

Obviously, you can do the same with map , but in this case you do not need it, and you must also use each to print each element. Code will 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 } 
+3
source

This is described in the Ruby documentation in several places, but the easiest to understand for your use in the Array documentation for each :

 each { |item| block } β†’ ary each β†’ Enumerator 

Calls this block once for each element in self, passing this element as a parameter. Returns an array.

If the block is not specified, the counter is returned.

 a = [ "a", "b", "c" ] a.each {|x| print x, " -- " } 

gives:

 a -- b -- c -- 

Notice that it says: "Returns the array itself."

Compare this to map :

 map { |item| block } β†’ new_ary map β†’ Enumerator 

Invokes this block once for each self element.

Creates a new array containing the values ​​returned by the block.

See also List # collect.

If no blocks are specified, a counter is returned instead.

 a = [ "a", "b", "c", "d" ] a.collect { |x| x + "!" } #=> ["a!", "b!", "c!", "d!"] a.map.with_index { |x, i| x * i } #=> ["", "b", "cc", "ddd"] a #=> ["a", "b", "c", "d"] 

Notice that it says: "Creates a new array containing the values ​​returned by the block."

This example should help to find out above:

 foo = [1,2,3] foo.each { |i| puts i + 1 } # => [1, 2, 3] foo.map { |i| i + 1 } # => [2, 3, 4] # >> 2 # >> 3 # >> 4 

where # => is the return value of the block, and # >> is the captured STDOUT from puts .

And knowing all this, use each when you want to display elements in an array or retrieve and reuse these elements as parameters or build things. Use map when you want to change the elements of an array to something else.

+1
source

In the first case, map :

  z = [1,2,3].map {|x| x + 1} 

will take each element in the given array and perform the operation in the block and return a new array, so it returns [2,3,4] .

.each executes a block for each of the elements of the array, and it does not change anything in the array, so here it executes x + 1 , but it does not store it anywhere, so in the second case, it simply returns the array.

Now in the third example that you published, you print the output in the block itself. Again, there are no changes in the array itself.

0
source

The difference is that each performs an action for each element of the array, returning the original array. The performed action may have mutated the element.

While map takes an action on each element in the array and returns its result as an array.

0
source

All Articles