Map

Imagine you have a list of mixed-case strings, and you want to convert it to a new list of strings that are all lowercase.

Imagine that you have a list of ingredients, and you want to convert it to a new list of li tags.

Imagine that you have a list of 1-based serial numbers and you want to convert them to a new list of 0-based indices.

Each of these situations can be solved by writting code that follows this pattern:

newItems = []
for each oldItem in oldItems
convert oldItem to newItem
add newItem to newItems

This pattern has been abstracted into the Array.map method. The only piece that changes is the conversion operation. The conversion operation is a function that receives a single item as a parameter and turns it into a new item. You pass this conversion function in as a parameter.

Using map and arrow functions for your predicates, you solve all three of the problems above with very compact code:

// Lowercase all strings.
const lowers = strings.map(string => string.toLowerCase());

// Convert list of ingredients into a ul.
const lis = ingredients.map(ingredient => `<li>${ingredient}</li>`);
const li = `<ul>${lis.join()}</ul>`;

// Turn 1-based serial numbers into 0-based indices.
const indices = serials.map(serial => serial - 1);

With filter, the resulting array may be smaller than the original. In contrast, map produces an array that is the same size as the original.

Try creating an array of multi-word strings in your browser's console and converting it to an array of kebab-style identifiers. For example, ['big banner', 'player one tile'] maps to ['big-banner', 'player-one-tile'].

Try creating an array of the numbers 1 through 5 and turning these into a list of a tags whose URLs are of the form page#.html.

As with forEach and filter, the element's index is passed as a second parameter to your predicate.

There many other higher-order functions available for arrays, including every, some, find, and findIndex.