Map

Dear Computer

Chapter 4: Functions

Map

The map pattern is similar to the for-each pattern, but instead of achieving some side effect for each item, the loop transforms each item into a new item. Perhaps each string is turned into a lowercase version of the same text. Perhaps each number is converted to some other number. Perhaps each image is resized to some new image. All the new items are collected together in a new array that has the exact same size as the original. Visually, the map pattern performs this operation:

An array of triangles mapped into an array of parallelograms

Map is implemented as in the following pseudocode:

Pseudocode
class Collection
  items = ...

  function map(transformOne)
    newItems = new array(items.size)
    for i in 0 to items.size
      newItems[i] = transformOne(items[i], i)
    return newItems

Ruby implements the map pattern in the map method of its Array class. With map, you may transform your arrays without the pageantry of loops:

Ruby
lengths = words.map { |word| word.length }
kilometers = miles.map { |mile| mile * 1.60934 }
commands = commands.map { |command| command.downcase }

If an index is needed in order to transform an item, Ruby provides a with_index method that may be called on the iterator that map returns. This script turns an array of rules into an array of numbered rules using indices:

Ruby
numbered_rules = rules.map.with_index do |rule, i|
  "#{i + 1}. #{rule}"
end

We will examine how other languages have implemented the map pattern later on when we discuss lambdas and closures. Python has its own map function, but the community favors transforming one list into another using a list comprehension:

Python
kilometers = [mile * 1.60934 for mile in miles]

Haskell supports both list comprehensions and map, but the community tends to favor map for its consistency with the rest of the language.

← For-eachFilter →