Execute Program

JavaScript Arrays: Map

Welcome to the Map lesson!

The JavaScript "map" method on arrays builds a new array by calling a function on each of the old array's elements. This is often simpler than a loop.

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • We often want to build a new array out of an existing array. For example, we might want to convert an array of dollar prices into cents, multiplying each by 100.

  • .map is good for jobs like this. We give .map a callback, which .map calls on each array element. .map returns a new array of the values returned by those function calls.

  • >
    const dollarAmounts = [10, 20, 30];
    const centAmounts = dollarAmounts.map(n => n * 100);
    centAmounts;
    Result:
    [1000, 2000, 3000]Pass Icon
  • We can use .map to uppercase each string in an array.

  • >
    ['a', 'b', 'c'].map(x => x.toUpperCase());
    Result:
    ['A', 'B', 'C']Pass Icon
  • Note that .map doesn't change the original array.

  • >
    const nums = [1, 2, 3];
    nums.map(n => n * 10);
    nums[0];
    Result:
    1Pass Icon
  • In a previous lesson, we built an array of people's names using .forEach.

  • >
    const people = [
    {name: 'Amir'},
    {name: 'Betty'},
    ];
    const names = [];
    people.forEach(person => {
    names.push(person.name);
    });
    names;
    Result:
    ['Amir', 'Betty']Pass Icon
  • With .map, we can avoid pushing each element onto a new array. Instead, we map the original array elements to create new elements in a single operation. Note how much simpler and cleaner this version looks!

  • >
    const people = [
    {name: 'Amir'},
    {name: 'Betty'},
    ];
    const names = people.map(person => person.name);
    names;
    Result:
    ['Amir', 'Betty']Pass Icon
  • When repeated hundreds or thousands of times across a software system, this difference can really add up.

  • Like .forEach, the callback function we pass to .map takes an optional second argument: the element's index. This can be useful when we need to keep track of element count, or only operate on every nth element.

  • >
    const people = [
    {name: 'Amir'},
    {name: 'Betty'},
    ];
    people.map((person, i) => {
    return (i + 1) + ': ' + person.name;
    });
    Result:
  • >
    const numbers = [10, 10, 10];
    numbers.map((e, i) => e * i);
    Result:
    [0, 10, 20]Pass Icon
  • In JavaScript, any function without a return statement implicitly returns undefined.

  • >
    function double(n) {
    const doubled = n * 2;
    }
    double(3);
    Result:
    undefinedPass Icon
  • If we forget to return an element in the callback function, the same thing happens: our callback returns undefined. The undefineds will end up in our mapped array. This is an easy mistake to make.

  • >
    [1, 2].map(n => {
    n * 2;
    });
    Result:
    [undefined, undefined]Pass Icon
  • One-line arrow functions (without curly braces) return their values automatically, so that's one way to avoid the problem.

  • >
    [1, 2, 3].map(n => n * 2);
    Result:
    [2, 4, 6]Pass Icon
  • Here's a code problem:

    The .map below should return an array of doubled numbers. Instead, it returns an array of undefineds. Modify it to correctly double each number.

    [1, 2, 3].map(n => n * 2);
    Goal:
    [2, 4, 6]
    Yours:
    [2, 4, 6]Pass Icon
  • .map can make code easier to read because it doesn't mutate the original array. We don't have to ask "is this modifying an array that's visible to other code in the system?" When you're tempted to reach for a for loop, for ... of loop, or the .forEach method, consider whether .map might be a better solution.