Learn JavaScript

Метод map в JavaScript: преобразование массива

map - это метод массива, который преобразует элементы и возвращает новый массив той же длины. Исходный массив при этом не меняется.

Идея map

Есть массив, нужен новый массив, где каждый элемент вычислен по правилу.

const nums = [1, 2, 3];

const doubled = nums.map(n => n * 2);

console.log(doubled); // [2, 4, 6]
console.log(nums);    // [1, 2, 3]
  • nums остался прежним
  • doubled - новый массив

Синтаксис

array.map((value, index, array) => {
  return newValue;
});
  • value - текущий элемент
  • index - индекс элемента
  • array - исходный массив (редко нужен)

Самое важное правило: колбэк должен вернуть новое значение для элемента.

Примеры преобразований

1) Приведение к строкам

const nums = [10, 20, 30];

const asText = nums.map(n => String(n));
console.log(asText); // ["10", "20", "30"]

2) Преобразование регистра

const names = ["Sam", "Alex", "Kim"];

const lower = names.map(name => name.toLowerCase());
console.log(lower); // ["sam", "alex", "kim"]

3) Использование index

Иногда индекс нужен для вычисления значения:

const items = ["a", "b", "c"];

const labeled = items.map((value, index) => (index + 1) + ". " + value);
console.log(labeled); // ["1. a", "2. b", "3. c"]

4) Преобразование массива объектов

Частый сценарий - взять одно поле:

const users = [
  { id: 1, name: "Sam" },
  { id: 2, name: "Alex" },
];

const names = users.map(u => u.name);
console.log(names); // ["Sam", "Alex"]

Или создать новые объекты в другом формате:

const users = [
  { id: 1, name: "Sam" },
  { id: 2, name: "Alex" },
];

const cards = users.map(u => ({
  label: u.name,
  value: u.id
}));

console.log(cards);
// [{ label: "Sam", value: 1 }, { label: "Alex", value: 2 }]

map не для фильтрации и не для побочных эффектов

map не удаляет элементы

map всегда возвращает массив той же длины. Если нужно оставить только часть элементов, используется filter (будет следующим шагом).

Неправильная идея:

const nums = [1, 2, 3, 4];

const evens = nums.map(n => {
  if (n % 2 === 0) return n;
  return null;
});

console.log(evens); // [null, 2, null, 4]

Это не фильтрация, а преобразование.

map не нужен, если результат не используется

Если нужно только пройти по массиву и что-то вывести, чаще подходит forEach.

const nums = [1, 2, 3];

nums.forEach(n => {
  console.log(n);
});

Частые ошибки

1) Забыли return в фигурных скобках

Если стрелочная функция записана с {}, то return обязателен.

const nums = [1, 2, 3];

const doubled = nums.map(n => {
  return n * 2;
});

console.log(doubled); // [2, 4, 6]

Если return забыть, получится undefined:

const nums = [1, 2, 3];

const doubled = nums.map(n => {
  n * 2;
});

console.log(doubled); // [undefined, undefined, undefined]

2) Ожидание, что map изменит исходный массив

map не мутирует массив:

const nums = [1, 2, 3];

nums.map(n => n * 2);

console.log(nums); // [1, 2, 3]

Новый массив нужно сохранить:

const nums = [1, 2, 3];

const doubled = nums.map(n => n * 2);
console.log(doubled); // [2, 4, 6]

Что стоит запомнить

  • map преобразует массив и возвращает новый массив той же длины.
  • Исходный массив не меняется.
  • Колбэк должен возвращать новое значение для каждого элемента.
  • Для фильтрации используется filter, для перебора без результата - forEach.