map transforms every element
A method built to return something new
The last course set out each's job: run code once per element for its side effects, and hand back the same collection. map does the opposite job.
numbers = [1, 2, 3]
doubled = numbers.map { |n| n * 2 }
doubled # => [2, 4, 6]
numbers # => [1, 2, 3], untouched
map calls the block once per element, like each, but collects each value the block computes into a new array and returns it. numbers is left alone, the "returns new, doesn't mutate" pattern the arrays course showed for sort.
The result is always the same length as the original
words = ["cat", "elephant", "dog"]
lengths = words.map { |w| w.length }
lengths # => [3, 8, 3]
Three words in, three numbers out. map never skips or adds an element, so the result lines up with the original: lengths[0] describes words[0], lengths[1] describes words[1], and so on.
What map's block returns matters
Here's the real difference from each. each throws the block's return value away. For map, that value is the point: it becomes the matching element of the new array.
numbers = [1, 2, 3]
numbers.each { |n| n * 2 } # => [1, 2, 3], the *2 is discarded
numbers.map { |n| n * 2 } # => [2, 4, 6], the *2 becomes the result
Same block and same input, but different return values, because the two methods treat the block's result differently.
Key takeaways
mapcollects each block result into a new array and leaves the original untouched.- The result always has the same length as the original, lined up position by position.
- The block's return value becomes the new element;
eachdiscards it. - Use
mapwhen the goal is a transformed collection, not a side effect.
Keep going with lesson 2
map vs each
Choose each for side effects and map for a new collection, based on what happens to the block's result.
A free account also gives you the quizzes, your progress and notes, and the discussion.