- Разница между Array.prototype.flatMap и Array.prototype.flat
- Практические примеры использования Array.prototype.flatMap
- Практические примеры использования Array.prototype.map
- Как реализовать Array.prototype.flatMap
- Как реализовать Array.prototype.flatMap
Разница между Array.prototype.flatMap и Array.prototype.flat
Array.prototype.flat — это метод, позволяющий сглаживать вложенные массивы до определенного уровня глубины. По умолчанию он сгладит один уровень:
const nestedNumbers = [1, [2, 3], [4, [5, 6]]]; const flatResult = nestedNumbers.flat(); console.log(flatResult); // [1, 2, 3, 4, [5, 6]]
В этом случае flat сглаживает массив только на один уровень. Если вам нужно сгладить до более глубоких уровней, вы можете указать аргумент глубины:
const resultFlatDeep = nestedNumbers.flat(2); console.log(resultFlatDeep); // [1, 2, 3, 4, 5, 6]
С другой стороны, Array.prototype.flatMap представляет собой комбинацию карты и плоскости. Он применяет функцию сопоставления к каждому элементу массива, а затем сводит результат в новый массив, но сглаживает только на один уровень в глубину. Давайте посмотрим на пример:
const numbers = [1, 2, 3, 4]; const result = numbers.numbers(numero => [numero, numero * 2]); console.log(result); // [1, 2, 2, 4, 3, 6, 4, 8]
Таким образом, Array.prototype.flat — это метод, используемый для выравнивания вложенных массивов до определенного уровня глубины, в то время как Array.prototype.flatMap сочетает отображение и выравнивание массива в одной операции, облегчая преобразование и выравнивание массивов в определенные случаи.
Практические примеры использования Array.prototype.flatMap
Пример 1: Извлечение свойств объектов в массиве
Предположим, у вас есть массив объектов, представляющих людей и их друзей, и вы хотите извлечь все имена в один массив:
const persons = [ { name: 'Ana', friends: [{ name: 'Charles' }, { name: 'Sophie' }] }, { name: 'Peter', friends: [{ name: 'Maria' }, { name: 'John' }] } ]; const names = persons.flatMap(person => [ person.name, ...person.friends.map(friend => friend.name) ]); console.log(names); // ['Ana', 'Charles', 'Sophie', 'Peter', 'Maria', 'John']
Пример 2. Фильтрация и преобразование значений в массиве
Представьте, что у вас есть массив чисел, и вы хотите получить новый массив, содержащий только повторяющиеся четные числа:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9] const evenNumbersDuplicates = numeros.flatMap(number => number % 2 === 0 ? [number * 2] : [] ); console.log(evenNumbersDuplicates); // [4, 8, 12, 16]
Пример 3: Объединение элементов массива в двумерный массив
Учтите, что у вас есть два массива одинаковой длины, и вы хотите объединить элементы обоих массивов в новый двумерный массив:
const array1 = ['a', 'b', 'c']; const array2 = [1, 2, 3]; const combined = array1.flatMap((element, index) => [ [element, array2[index]] ]); console.log(combined); // [['a', 1], ['b', 2], ['c', 3]]
Ejemplos prácticos del uso de Array.prototype.flat
Пример 1. Сведение вложенных массивов
Представьте, что у вас есть двумерный массив чисел, и вы хотите преобразовать его в одномерный массив:
const array = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; const flattened = array.flat(); console.log(flattened); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
Пример 2: Объединение нескольких массивов в один
Предположим, у вас есть массив, содержащий несколько массивов слов, и вы хотите объединить их в один массив:
const wordsGrouped = [ ['apple', 'banana', 'cherry'], ['dog', 'cat', 'elephant'], ['sun', 'moon', 'star'] ]; const words = wordsGrouped.flat(); console.log(words); // ['apple', 'banana', 'cherry', 'dog', 'cat', 'elephant', 'sun', 'moon', 'star'.]
Пример 3: Удаление пустых элементов в массиве
Учтите, что у вас есть массив с пустыми элементами, и вы хотите их удалить:
const withEmptyElements = [1, , 2, , 3, 4, , 5]; const withoutEmptyElements = withEmptyElements.flat(); console.log(withoutEmptyElements); // [1, 2, 3, 4, 5]
Стоит отметить, что в этом случае flat удаляет пустые элементы только потому, что они находятся на уровне вложенности.
Как реализовать Array.prototype.flatMap
Если вы используете версию JavaScript до ES12 и у вас нет доступа к Array.prototype.flatMap, вы можете реализовать свою собственную версию, используя Array.prototype.reduce и Array.prototype.concat. Вот пример того, как это сделать:
if (!Array.prototype.flatMap) { Array.prototype.flatMap = function (callback, thisArg) { if (this == null) { throw new TypeError( "Array.prototype.flatMap called on null or undefined" ); } if (typeof callback !== "function") { throw new TypeError(callback + " is not a function"); } const array = Object(this); const len = array.length >>> 0; const newArray = []; for (let i = 0; i < len; i++) { if (i in array) { const mappedValue = callback.call(thisArg, array[i], i, array); newArray.push(...mappedValue); } } return newArray; }; }
Эта реализация использует reduce и concat для применения функции сопоставления и сведения результата в новый массив. Реализация также проверяет, имеет ли это значение null или undefined и является ли обратный вызов функцией, что необходимо для обеспечения согласованности с поведением Array.prototype.flatMap в ES12.
После включения этого кода в ваш проект вы можете использовать flatMap так же, как и нативную версию:
const numbers = [1, 2, 3, 4]; const result = numbers.flatMap(number => [number, number * 2]); console.log(result); // [1, 2, 2, 4, 3, 6, 4, 8]
Обратите внимание, что хотя эта реализация работает в большинстве случаев, могут быть небольшие отличия от поведения Array.prototype.flatMap в ES12. Всегда рекомендуется обновляться до последней версии JavaScript, когда это возможно, чтобы воспользоваться собственными функциями и улучшениями производительности.
Как реализовать Array.prototype.flat
Если вы используете версию JavaScript до ES12 и у вас нет доступа к Array.prototype.flat, вы можете реализовать свою собственную версию, используя Array.prototype.reduce и Array.prototype.concat. Вот пример того, как это сделать:
if (!Array.prototype.flat) { Array.prototype.flat = function (depth = 1) { if (this == null) { throw new TypeError("Array.prototype.flat called on null or undefined"); } if (depth < 0) { return this.slice(); // Returns a copy of the original array if the depth is negative } const flattenArray = (arr, currentDepth) => { if (currentDepth === depth) { return arr.slice(); } return arr.reduce((acc, item) => { if (Array.isArray(item)) { acc.push(...flattenArray(item, currentDepth + 1)); } else { acc.push(item); } return acc; }, []); }; return flattenArray(this, 0); }; }
В этой реализации используется reduce and concat для рекурсивного выравнивания массива. Функция flattenArray вызывается рекурсивно в соответствии с глубиной, указанной в аргументе depth. Реализация также проверяет, является ли это значением null или undefined, что необходимо для обеспечения согласованности с поведением Array.prototype.flat в ES12.
После включения этого кода в свой проект вы можете использовать flat так, как хотели бы. родная версия:
const nestedNumbers = [1, [2, 3], [4, [5, 6]]]; const resultFlat = nestedNumbers.flat(); console.log(resultFlat); // [1, 2, 3, 4, [5, 6]]
Обратите внимание, что хотя эта реализация работает в большинстве случаев, могут быть небольшие отличия от поведения Array.prototype.flat в ES12. Всегда рекомендуется обновляться до последней версии JavaScript, когда это возможно, чтобы воспользоваться собственными функциями и улучшениями производительности.
Хулио Лейва Диас 👨🏻💻 FrontEnd Software Engineer