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.
.mapis good for jobs like this. We give.mapa callback, which.mapcalls on each array element..mapreturns 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]
We can use
.mapto uppercase each string in an array.>
['a', 'b', 'c'].map(x => x.toUpperCase());Result:
['A', 'B', 'C']
Note that
.mapdoesn't change the original array.>
const nums = [1, 2, 3];nums.map(n => n * 10);nums[0];Result:
1
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']
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']
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.maptakes 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]
In JavaScript, any function without a
returnstatement implicitly returnsundefined.>
function double(n) {const doubled = n * 2;}double(3);Result:
undefined
If we forget to
returnan element in the callback function, the same thing happens: our callback returnsundefined. Theundefineds will end up in our mapped array. This is an easy mistake to make.>
[1, 2].map(n => {n * 2;});Result:
[undefined, undefined]
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]
Here's a code problem:
The
.mapbelow should return an array of doubled numbers. Instead, it returns an array ofundefineds. Modify it to correctly double each number.[1, 2, 3].map(n => n * 2);- Goal:
[2, 4, 6]
- Yours:
[2, 4, 6]
.mapcan 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 aforloop,for ... ofloop, or the.forEachmethod, consider whether.mapmight be a better solution.