Автор оригинала: FreeCodeCamp Community Member.
Влагоподъемность и элегантность решения приводится в действие инструментами, которые мы должны решить конкретную проблему. Хотя цель решения проблем – решить проблему , это методы должны двигаться к наиболее элегантному пути. Однако путешествие на такое решение, кажется, лежит на асимптотической кривой. Совершенство становится все ближе и ближе, но навсегда остается вне досягаемости.
Проблема
Представьте, что имейте массив и необходимость изменить каждый элемент в массиве. Возможно, например, принимая массив высот в дюймах и нуждающийся в преобразовании их в сантиметры. Или, возможно, преобразование массива температур в Celcius в Фаренгейт. Если вы новичок в программировании, ваш разум может немедленно пойти в некоторую форму цикла. И угадай что? Я уверен, что вы могли бы сделать это работать.
Тем не менее, я здесь, чтобы дать вам еще один инструмент – что-то, чтобы заставить вас немного ближе к элегантному: Array.prototype.map ()
Отказ
карта
Метод позволяет преобразовывать каждый элемент массива, не влияя на исходный массив. Это считается Функция высшего порядка и методика функциональной программирования, поскольку он принимает функцию в качестве аргумента, и мы выполняем вычисление без мутации состояния нашего приложения.
К концу этого урока мы узнаем, как карта
Работает и написать наш собственный метод прототипа массива.
Так что делать .map () делать?
Допустим, у вас есть массив температур в Цельсей, который вы хотите преобразовать в Фаренгейт.
Есть несколько способов решения этой проблемы. Одним из способов можно написать для
Цикл для создания массива температур Фаренгейта из данных температур Цельсии.
С для
петля мы можем написать:
const celciusTemps = [22, 36, 71, 54]; const getFahrenheitTemps = (function(temp) { const fahrenheitTemps = []; for (let i = 0; i < celciusTemps.length; i += 1) { temp = celciusTemps[i] * (9/5) + 32 fahrenheitTemps.push(temp); } console.log(fahrenheitTemps); [71.6, 96.8, 159.8, 129.2 })();
Пара вещей, чтобы отметить:
- Оно работает.
- Мы используем немедленно вызываемое выражение функции (IIFE), чтобы избежать также необходимости вызывать функцию.
- Это немного многословна и не очень элегантно.
Карта
Позволяет нам принять вышеуказанный код и рефакторировать его к следующему:
const fahrenheitTemps = celciusTemps.map(e => e * (9/5) + 32); console.log(fahrenheitTemps); // [71.6, 96.8, 159.8, 129.2]
Так как работает карта?
Карта
принимает функцию и применяет эту функцию для каждого элемента в массиве. Мы могли бы написать карта
немного более многословную с ES5, чтобы увидеть это немного более четко.
const fahrenheitTemps = celciusTemps .map(function(elementOfArray) { return elementOfArray * (9/5) + 32; }); console.log(fahrenheitTemps); // [71.6, 96.8, 159.8, 129.2]
Если наша функция карты может сказать, что это делает, это скажет:
«Для каждого элемента в массиве я умножу его через (9/5), затем добавьте 32. Когда это сделано, я возвращаю результат в качестве элемента в новом массиве под названием Fahrenheittemps.
Давайте посмотрим на более распространенное использование случая. Давайте предположим, что у нас есть массив люди
объекты. Каждый объект имеет Имя
и возраст
Пара ключа-значения. Мы хотим создать переменную, которая только имена всех в массиве. С нашей для
Метод петли мы могли бы написать:
const people = [ {name: Steve, age: 32}, {name: Mary, age: 28}, {name: Bill, age: 41}, ]; const getNames = (function(person) { const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();
С карта
:
const names = people.map(e => e.name); console.log(names) // [Steve, Mary, Bill];
Уведомление здесь Мы ничего не трансформируемся, мы просто возвращаем пару ключ Имя
Отказ
Опять же для
петли работает. Но это Verbose, и мы должны создать новую пользовательскую функцию каждый раз, когда мы хотим сделать другое преобразование. Основная часть программирования пишет сухой код (не повторяйте себя). Эти функции более высокого порядка, такие как карта, позволяет делать более сложное программирование в меньшем количестве строк кода, чем мы могли без них.
Изобретение колеса:
Чтобы лучше понять, что происходит под капотом, мы сделаем нашу собственную функцию карты, которую мы прикрепим к прототипу массива.
Во-первых, чтобы прикрепить метод прототипа к массиву, мы напишем:
Array.Prototype.
Так для нас:
Array.prototype.mymap = <Наш код>
Но какой будет наш код?
У нас уже есть логика, которую нам нужна от для
петли выше. Все, что нам нужно сделать, это немного рефакторет. Давайте рефокторируем последнюю функцию, которую мы написали getnames ()
Отказ
Помните, что эта функция взяла человека (другими словами, элемент нашего массива), сделал пользовательское преобразование к этому элементу (с помощью для
Loop и некоторая логика) и вернула массив имен (или новый массив ).
const getNames = (function(person) { const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();
Во-первых, давайте изменим имя нашей функции. В конце концов, этот новый метод не предполагает, что знают, какой массив он будет действовать на:
const myMap = (function(person) { //Changed name const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();
Во-вторых, мы создаем нашу собственную версию .map ()
Отказ Мы знаем, что это сделает функцию, которую предоставляет пользователь. Давайте изменим параметр, наша функция берет:
// It is a bit verbose, but a very clear parameter name const myMap = (function(userProvidedFunction) { const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();
Наконец, мы не имеем представления, какой массив этот метод будет действовать. Итак, мы не можем обратиться к люди.length
Но мы может Обратитесь к Это. Длина
Отказ это
, вернет массив метод действует на. Также давайте убрать некоторые другие имена переменной:
const myMap = (function(userProvidedFunction) { // change variable name const newArr = []; // use "this.length" for (let i = 0; i < this.length; i += 1) { // use "this[i]", and change variable name const newElement = this[i]; // update the array we push into newArr.push(newElement); } // Return the newly created array return newArr; })();
Мы почти там, но есть одна вещь, которую мы забываем. Мы не преобразовали массив! Все, что мы сделали выше, возвращают старый массив. Мы должны применить предоставленную пользователем функцию к каждому элементу массива:
const myMap = (function(userProvidedFunction) { const newArr = []; for (let i = 0; i < this.length; i += 1) { /* Transform the element by passing it into the * user-provided function */ const newElement = userProvidedFunction(this[i]); newArr.push(newElement); } return newArr; })();
Наконец, мы можем прикрепить нашу новую функцию для Array.Prototype
Отказ
Array.Prototype. Mymap;
Конечная проверка здравоохранения:
const myArray = [1, 2, 3]; // Multiply each element x 2 const myMappedArray = myArray.myMap(e => e * 2) console.log(myMappedArray) // [2, 4, 6];
Резюме
Карта
это метод прототипа, предлагаемого массивами. За кулисами он итализатор с помощью массива, применяя предоставленную пользователем функцию для каждого элемента. В конечном итоге он возвращает новый массив с преобразованными значениями. Это делает это без мутации исходного массива. Поскольку параметр, который требуется функция, она считается функцией более высокого порядка. Кроме того, его использование попадает в функциональную парадигму программирования.
Спасибо за прочтение!
ворота