Как стать автором
Обновить

ECMAScript Proposal: Array.prototype.{flat,flatMap}

JavaScript *

Нововведения в ECMAScript



Здравствуйте читатели Хабр. Предлагаю вашему вниманию интересную штуку которая в скором времени появится уже появилась в стандарте ECMAScript. Она уже доступна почти во всех браузерах и весь функционал тоже. Это нововведение всего лишь сахар-обертка и ее можно решить своими средствами и это я вам тоже покажу. Но этот сахар позволит нам писать кода меньше, ведь мы это так любим. Итак, добавляется базовые функции к массиву, в данном случае их 2, которые позволят нам разворачивать многоуровневые массивы в один или более уровней вложенности. Да да и все это как говориться из коробки


ECMAScript Proposal: Array.prototype.{flat,flatMap}


Этот Proposal когда то был известен под именем Array.prototype.flat{ten, Map}. Он имеет статус stage 3 4 из TC39 то есть уже Candidate Finished. Я думаю стоит немного отвлечься и рассказать о этом самом TC39 и о стандартах, кто знаком могут пропустить сие отступление. итак:


Стандарты JavaScript и как его готовят.


ECMAScript


ECMAScript — это стандарт, который развивается и поддерживается ассоциацией ECMA International. Он был принят Генеральной Ассамблеей Ecma в июне 1997. А если точнее, ECMAScript — это стандарт ECMA-262, который называется «Спецификация языка ECMAScript». Стандарт создавался на основе оригинальной версии JavaScript от Брендана Айха из Netscape и интерпретатора JScript от Microsoft, но с тех пор значительно развился.


JavaScript — это реализация спецификации ECMAScript. Это означает, что по мере того, как у спецификации появляются новые черновики или опубликованные редакции, разработчики браузеров и фреймворков вроде Node.js должны последовательно внедрять новый функционал. Для этого вносятся изменения в движки, которые эти браузеры и фреймворки используют для интерпретирования и выполнения кода JavaScript.


Зачем нужна спецификация? В различных браузерах используются различные движки JavaScript, например, V8 в Chrome, SpiderMonkey в Firefox, и так далее. Когда вы пишете на JavaScript, вы ожидаете, что все движки во всех окружениях будут разбирать и выполнять ваш код абсолютно одинаково. Без стандартизованной спецификации любой из этих движков был бы волен исполнять JavaScript как ему вздумается, очевидно, что это не очень хорошо.


TC39


Ecma International Technical Committee 39 (он же TC39) — комитет очень умных людей, он связан с группой участников тоже кстати умные. Они все дружно собираются вместе на встречах комитета приблизительно раз в два месяца и обсуждают заранее подготовленные списки вопросов.
Задачей TC39 является поддержка и обновление упомянутой ранее спецификации ECMAScript, после обсуждения и всеобщего согласия. Сюда относятся синтаксис языка, семантика, библиотеки и сопутствующие технологии, на которых основывается язык.


Этот процесс определён TC39. Всё начинается с черновика функционала, расширяющего или изменяющего спецификацию. Такие черновики часто исходят от сообществ разработчиков, или же от самих участников TC39. Если предложение оказывается достойным, черновик получает статус официального предложения.


Затем на своём пути от идеи до публикации предложение проходит несколько определенных стадий. Они пронумерованы от нуля до четырёх мыж программисты:


[“Strawman”, “Proposal”, “Draft”, “Candidat”, “Finished”]

Переход на любую следующую стадию требует одобрения TC39. Если предложение добралось до стадии 4, можно ожидать, что его включат в следующую официально опубликованную редакцию спецификации стандарта ECMA-262, и в итоге оно появится в окружении, которое выполняет JavaScript. Больше об этом процессе вы можете узнать из самого документа.


Все существующие предложения на введения в стандарт можно посмотреть тут на github
ну теперь поехали дальше ...


Array.prototype.flat


Метод flat() возвращает новый массив,


var newArray = arr.flat(depth);

в котором все элементы вложенных под массивов были рекурсивно "подняты" на указанный уровень depth.


Пример:


const arr1 = [1, 2, [3, 4]];
arr1.flat(); //? [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); //? [1, 2, 3, 4, [5, 6]]

const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); //? [1, 2, 3, 4, 5, 6]

Также существует и побочное действие, он удаляет не определенные элементы массива


Пример:


const arr4 = [1, 2, , 4, 5];
arr4.flat(); //? [1, 2, 4, 5]

Рубрика делаем сами


Используем reduce и concat


Пример:


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

function flattenDeep(arr1) {
   return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}
flattenDeep(arr1); //? [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

Array.prototype.flatMap



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


var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
    // return element for new_array
}[, thisArg])

callback — Функция которая производит элементы нового массива, принимает три аргумента:


  1. currentValue — Текущий обрабатываемый элемент массива.
  2. index (необязательный) — Индекс обрабатываемого элемента в массиве.
  3. array (необязательный) — Массив по которому осуществляется обход.
    thisArg (необязательный) — Значение используемое в качестве this при вызове функции callback.
    Возвращаемое значение — Новый массив, каждый элемент которого является результатом выполнения функции callback и "поднят" на уровень 1.

пример:


[
    { x: 1, y: 2 }, 
    { x: 3, y: 4 }, 
    { x: 5, y: 6 }
].flatMap(c => [c.x, c.y])  //?  [1, 2, 3, 4, 5, 6]

// or

const orders = [
    {
        orderId: 42,
        items: [
            {name: 'soap', price: 1.99},
            {name: 'shampoo', price: 4.99}
        ]
    },
    {
        orderId: 1337,
        items: [
            {name: 'toothpaste', price: 5.59},
            {name: 'toothbrush', price: 8.99}
        ]
    }
];

orders.flatMap(i => i.items.map(i => i.name)); //? ["soap", "shampoo", "toothpaste", "toothbrush"]

Рубрика делаем сами


var arr1 = [1, 2, 3, 4];

arr1.reduce((acc, x) => acc.concat([x * 2]), []);
// [2, 4, 6, 8]

Заключение


Помните, что этот функционал добавляется в язык неспроста. Причины, по которым умные люди из TC39 это делают — улучшение качества языка, абстрагирования, удобства пользования и другие. Изучите эти новшества заранее, и к тому моменту, как они будут официально опубликованы и станут везде поддерживаться, вы сможете не теряя времени сразу приняться за работу. Вы также можете позиционировать себя как эксперта по JavaScript в своей организации, способного предложить новые особенности языка, позволяющие улучшить как код, так и сам продукт.


ps: пока писалась статья :), Proposal перешел в stage 4
Array.prototype.{flat,flatMap} to stage 4, per 2019.01.29 TC39

Теги:
Хабы:
Всего голосов 33: ↑30 и ↓3 +27
Просмотры 11K
Комментарии 29
Комментарии Комментарии 29

Публикации

Истории

Работа