18

Possible Duplicate:
Array#each vs. Array#map

ruby-1.9.2-p180 :006 > ary = ["a", "b"]
 => ["a", "b"] 
ruby-1.9.2-p180 :007 > ary.map { |val| p val }
"a"
"b"
 => ["a", "b"] 
ruby-1.9.2-p180 :008 > ary.each { |val| p val }
"a"
"b"
 => ["a", "b"] 

ruby-1.9.2-p180 :009 > ary.map { |val| val << "2" }
 => ["a2", "b2"] 
ruby-1.9.2-p180 :010 > ary.each { |val| val << "2" }
 => ["a22", "b22"] 
Community
  • 1
  • 1
Jeremy Smith
  • 14,727
  • 19
  • 67
  • 114

4 Answers4

52

The side effects are the same which is adding some confusion to your reverse engineering.

Yes, both iterate over the array (actually, anything that mixes in Enumerable) but map will return an Array composed of the block results while each will just return the original Array. The return value of each is rarely used in Ruby code but map is one of the most important functional tools.

BTW, you may be having a hard time finding the documentation because map is a method in Enumerable while each (the one method required by the Enumerable module) is a method in Array.

As a trivia note: the map implementation is based on each.

DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
  • 5
    +1 for linking "map" to functional programming. "each" on the other hand is the usual imperative loop with side effects. – tokland Apr 16 '11 at 20:32
  • Map doesn't seem very 'functional' because changing the object in question changes the original object – j will Oct 26 '15 at 16:44
  • 1
    @j will, hmm, `map!` changes the original object but plain `map` creates a new array as the result. – DigitalRoss Nov 13 '15 at 18:09
  • `Array` does include `Enumerable`, but it provides its own (optimized) `map`. And `Array#map` is **not** based on `each`. – Stefan Sep 08 '17 at 08:07
7

definition from API docs: each: Calls block once for each element in self, passing that element as a parameter. map: invokes block once for each element of self. Creates a new array containing the values returned by the block.

so each is a normal loop, which iterates through each element and invokes given block

map generally used where you want another array mapped by some logic to existing one. You can also pass method as reference to map function like

[1,2,3].map(&:to_s)
Naren Sisodiya
  • 7,158
  • 2
  • 24
  • 35
2

Array#map is a collection of whatever is returned in the blocked for each element.

Array#each execute the block of code for each element, then returns the list itself.

You should check this Array#each vs. Array#map

Community
  • 1
  • 1
Bastardo
  • 4,144
  • 9
  • 41
  • 60
2

Each is just an iterator that gets the next element of an iterable and feeds to a block. Map is used to iterate but map the elements to something else, like a value multiplied by a constant. In your examples, they can be used interchangeably, but each is a more generic iterator that passes the element to a block.

Spyros
  • 46,820
  • 25
  • 86
  • 129