Кратко
Секция статьи "Кратко"Метод map
позволяет трансформировать один массив в другой при помощи функций-колбэка. Переданная функция будет вызвана для каждого элемента массива по порядку. Из результатов вызова функции будет собран новый массив.
Пример
Секция статьи "Пример"Создадим массив квадратов:
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]const squares = nums.map(function (num) { return num * num})
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9] const squares = nums.map(function (num) { return num * num })
Результат:
.
Либо можно сделать массив с объектами:
const objects = nums.map(function (num) { return { field: num, }})
const objects = nums.map(function (num) { return { field: num, } })
Результат:
.
Интерактивный пример:
Как пишется
Секция статьи "Как пишется"Как и другим похожим методам, map
необходимо передать колбэк-функцию, которая будет возвращать какое-то значение. Именно это значение попадёт в итоговый трансформированный массив.
Функция, которую мы передаём в метод map
, может принимать три параметра:
item
— элемент массива в текущей итерации;index
— индекс текущего элемента;arr
— сам массив, который мы перебираем.
Суммируем числа, индексы и длины массива:
const nums = [0, 1, 2, 3]const transformed = nums.map(function (num, index, arr) { return num + index + arr.length})
const nums = [0, 1, 2, 3] const transformed = nums.map(function (num, index, arr) { return num + index + arr.length })
Результат:
.
Как это понять
Секция статьи "Как это понять"Часто возникают ситуации, когда на основе одного массива нужно создать другой массив, как-нибудь трансформировав исходные значения. Это можно сделать, используя обычные циклы for
или while
:
const nums = [1, 2, 3, 4, 5]const transformed = []for (let i = 0; i < nums.length; i++) { const num = nums[i] const item = `${i}-${num}` transformed.push(item)}console.log(transformed)// ['0-1', '1-2', '2-3', '3-4', '4-5']
const nums = [1, 2, 3, 4, 5] const transformed = [] for (let i = 0; i < nums.length; i++) { const num = nums[i] const item = `${i}-${num}` transformed.push(item) } console.log(transformed) // ['0-1', '1-2', '2-3', '3-4', '4-5']
Задача решена, однако, как и другие встроенные методы массива, map
позволяет написать код короче и проще для понимания:
const nums = [1, 2, 3, 4, 5]const transformed = nums.map(function (num, i) { return `${i}-${num}`})
const nums = [1, 2, 3, 4, 5] const transformed = nums.map(function (num, i) { return `${i}-${num}` })
Результат тот же, но способ короче и проще.
Подсказки
Секция статьи "Подсказки"💡 map
возвращает новый массив, при этом исходный массив никак не изменится.
💡 При работе с map
необходимо возвращать значение из функции-колбэка. Если не вернуть значение — например, забыв обработать какую-то ветку условия, то в итоговом массиве будет undefined
:
const nums = [1, 2, 3, 4, 5]const transformed = nums.map(function (num) { if (num <= 3) { return "less" } // Забыли обработать эту ветку условия})// ['less', 'less', 'less', undefined, undefined]
const nums = [1, 2, 3, 4, 5] const transformed = nums.map(function (num) { if (num <= 3) { return "less" } // Забыли обработать эту ветку условия }) // ['less', 'less', 'less', undefined, undefined]
Передача контекста в колбэк-функцию
Секция статьи "Передача контекста в колбэк-функцию"Вторым аргументом map
может принимать значение, которое будет передано как контекст выполнения функции-колбэка:
const nums = [1, 2, 3]const otherData = { delta: 5 }const transformed = nums.map(function (num) { // this теперь ссылается на объект otherData return num + this.delta}, otherData)console.log(transformed)// [ 6, 7, 8 ]
const nums = [1, 2, 3] const otherData = { delta: 5 } const transformed = nums.map(function (num) { // this теперь ссылается на объект otherData return num + this.delta }, otherData) console.log(transformed) // [ 6, 7, 8 ]
Обратите внимание, что стрелочным функциям нельзя изменить контекст выполнения, поэтому передача второго аргумента ни на что не повлияет:
const nums = [1, 2, 3]const otherData = { delta: 5 }const transformed = nums.map((num) => { // this.delta в данном случае равен undefined return num + this.delta}, otherData)console.log(transformed)// [ NaN, NaN, NaN ]
const nums = [1, 2, 3] const otherData = { delta: 5 } const transformed = nums.map((num) => { // this.delta в данном случае равен undefined return num + this.delta }, otherData) console.log(transformed) // [ NaN, NaN, NaN ]
На практике
Секция статьи "На практике"🛠 При работе с React или другой похожей на неё библиотекой map
— это самый распространённый способ трансформировать массив данных в компоненты, которые в итоге будут на странице:
function SomeComponent() { const items = ['This', 'is', 'map!'] return ( <div> {items.map(item => <span>{item}</span>)} </div> )}
function SomeComponent() { const items = ['This', 'is', 'map!'] return ( <div> {items.map(item => <span>{item}</span>)} </div> ) }
🛠 Так как map
возвращает массив, то у полученного массива мы можем продолжать по цепочке вызывать другие методы массива, в том числе, новый map
, продолжая трансформацию новых данных:
const nums = [1, 2, 3, 4, 5]const result = nums.map(...).filter(...).map(...)
const nums = [1, 2, 3, 4, 5] const result = nums.map(...).filter(...).map(...)