Перейти к содержимому

45. flat, flatMap

Иллюстрация к уроку Привет! Сегодня мы разберем полезные методы массивов: flat и flatMap. Они позволяют элегантно работать с многомерными массивами, упрощая код и делая его более читаемым.

Метод flat() создает новый массив, в котором все элементы подмассивов рекурсивно “поднимаются” на указанную глубину. Представьте, что вы разворачиваете матрешку, чтобы достать все фигурки.

// Пример 1: Массив массивов
const arr1 = [1, 2, [3, 4]];
console.log(arr1.flat()); // Output: [1, 2, 3, 4]
// Пример 2: Массив с большей глубиной вложенности
const arr2 = [1, 2, [3, 4, [5, 6]]];
console.log(arr2.flat()); // Output: [1, 2, 3, 4, [5, 6]] (по умолчанию глубина 1)
// Пример 3: Указываем глубину разворачивания
console.log(arr2.flat(2)); // Output: [1, 2, 3, 4, 5, 6]
// Пример 4: Использование Infinity для разворачивания до конца
const arr3 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
console.log(arr3.flat(Infinity)); // Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// Пример 5: Пропуск пустых слотов
const arr4 = [1, 2, , 4, 5];
console.log(arr4.flat()); // Output: [1, 2, 4, 5] (пустые слоты удаляются)

Метод flatMap() сначала применяет функцию к каждому элементу массива, а затем разворачивает результат в новый массив. Это как комбинация map и flat (с глубиной 1). Он более эффективен, чем последовательное использование map и flat, особенно если ваша функция map возвращает массивы.

// Пример 1: Преобразование и разворачивание
const arr = ["it's Sunny in", "", "California"];
const result = arr.flatMap(x => x.split(" "));
console.log(result); // Output: ["it's", "Sunny", "in", "", "California"]
// Пример 2: Фильтрация элементов (удаление пустых строк после split)
const arr2 = ["it's Sunny in", "", "California"];
const result2 = arr2.flatMap(x => x.split(" ")).filter(x => x !== "");
console.log(result2); // Output: ["it's", "Sunny", "in", "California"]
// Пример 3: Использование с числами
const numbers = [1, 2, 3, 4, 5];
const squaredPairs = numbers.flatMap(num => [num * num, num * num * num]);
console.log(squaredPairs); // Output: [1, 1, 4, 8, 9, 27, 16, 64, 25, 125]

Представьте себе веб-приложение, которое получает данные о комментариях из нескольких источников. Каждый источник может возвращать комментарии в разном формате, иногда в виде вложенных массивов.

// Пример: Получение комментариев из разных источников
const commentsFromApi1 = ["Comment 1", "Comment 2"];
const commentsFromApi2 = ["Comment 3", ["Comment 4", "Comment 5"]];
const commentsFromApi3 = ["Comment 6"];
const allComments = [commentsFromApi1, commentsFromApi2, commentsFromApi3];
// Использование flat для получения плоского списка комментариев
const flattenedComments = allComments.flat();
console.log(flattenedComments); // Output: ["Comment 1", "Comment 2", "Comment 3", ["Comment 4", "Comment 5"], "Comment 6"]
// Если нужно развернуть все уровни вложенности:
const fullyFlattenedComments = allComments.flat(Infinity);
console.log(fullyFlattenedComments); // Output: ["Comment 1", "Comment 2", "Comment 3", "Comment 4", "Comment 5", "Comment 6"]
// Пример с flatMap: Допустим, у нас есть массив предложений, и мы хотим получить массив всех слов
const sentences = ["Hello World", "JavaScript is fun", ""];
const words = sentences.flatMap(sentence => sentence.split(" "));
console.log(words); // Output: ["Hello", "World", "JavaScript", "is", "fun", ""]

В реальных проектах, flat и flatMap часто используются для обработки данных, полученных из API, для работы с DOM-структурой (например, когда нужно получить все дочерние элементы элемента, включая элементы во вложенных контейнерах), и для преобразования данных перед их отображением в пользовательском интерфейсе. Многие современные фреймворки и библиотеки (React, Vue, Angular) используют подобные методы внутри для упрощения работы с данными.

  • flat() создает новый плоский массив из многомерного массива.
  • Можно указать глубину разворачивания (по умолчанию 1).
  • flat(Infinity) разворачивает массив до максимальной глубины.
  • flatMap() выполняет map и flat одновременно (с глубиной 1).
  • flatMap() эффективнее, чем последовательное использование map и flat.
  • Оба метода полезны для обработки данных, полученных из API или DOM.