Что делает метод map в javascript
Перейти к содержимому

Что делает метод map в javascript

  • автор:

Array.prototype.map()

Метод map() создаёт новый массив с результатом вызова указанной функции для каждого элемента массива.

Синтаксис

Параметры

Функция, вызываемая для каждого элемента массива arr . Каждый раз, когда callback выполняется, возвращаемое значение добавляется в new_array .

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

Текущий обрабатываемый элемент массива.

Индекс текущего обрабатываемого элемента в массиве.

Массив, по которому осуществляется проход.

Необязательный параметр. Значение, используемое в качестве this при вызове функции callback

Возвращаемое значение

Новый массив, где каждый элемент является результатом callback функции.

Описание

Метод map вызывает переданную функцию callback один раз для каждого элемента, в порядке их появления и конструирует новый массив из результатов её вызова. Функция callback вызывается только для индексов массива, имеющих присвоенные значения, включая undefined . Она не вызывается для пропущенных элементов массива (то есть для индексов, которые никогда не были заданы, которые были удалены или которым никогда не было присвоено значение.

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

Если в метод map был передан параметр thisArg , при вызове callback он будет использоваться в качестве значения this . В противном случае в качестве значения this будет использоваться значение undefined . В конечном итоге, значение this , наблюдаемое из функции callback , определяется согласно обычным правилам определения this , видимого из функции.

Метод map не изменяет массив, для которого он был вызван (хотя функция callback может это делать).

Диапазон элементов, обрабатываемых методом map , устанавливается до первого вызова функции callback . Элементы, добавленные в массив после начала выполнения метода map , не будут посещены функцией callback . Если существующие элементы массива изменяются функцией callback , их значения, переданные в функцию, будут значениями на тот момент времени, когда метод map посетит их; удалённые элементы посещены не будут.

Примеры

Пример: отображение массива чисел на массив квадратных корней

Следующий код берёт массив чисел и создаёт новый массив, содержащий квадратные корни чисел из первого массива.

Пример: отображение массива чисел с использованием функции, содержащей аргумент

Следующий код показывает, как работает отображение, когда функция требует один аргумент. Аргумент будет автоматически присваиваться каждому элементу массива, когда map проходит по оригинальному массиву.

Пример: обобщённое использование map

Этот пример показывает, как использовать map на объекте строки String для получения массива байт в кодировке ASCII, представляющего значения символов:

Пример: обобщённое использование map вместе с querySelectorAll

Этот пример показывает, как пройтись по коллекции объектов, собранных с помощью querySelectorAll . В данном случае мы получаем все выбранные опции на экране и печатаем их в консоль:

Более простым способом будет использование метода Array.from() .

Пример: использование map для переворачивания строки

Более простым способом будет использование метода String.split() (см. пример обращение строки при помощи метода split()).

Пример: хитрый вариант использования

Распространённой практикой является использование колбэк-функции с одним аргументом (элемент, над которым производится операция). Некоторые функции также широко используется с одним аргументом, хотя они принимают дополнительные необязательные аргументы. Эти привычки могут привести к неожиданному поведению программы.

JS Array map method examples

It is a common task in javaScript projects to need to loop over the full contents of an array, and create some sort of product for each element in that array. There are methods like the Array for each method that can be used to do this sort of thing, along with other features in javaScript such as just doing such things with loops and the array bracket syntax. However there is an array prototype method that each javaScript developer should be aware of called array map.

I have wrote a post a long while back on the lodash map method that works more or less the same way as array map only it will work on most objects in general rather than just arrays. That of course is yet another option to be aware of if you are working on a project where lodash is part of the stack. However in this post I will be focusing more so on the native array map prototype method, as well as little tips and tricks that have to do with getting array map to work with objects in general as well as other native javaScriot examples for doing the same thing without array map.

1 — Array map basic example

The basic idea of the array map method is to call the map prototype method off of an instance of an array, and then pass a function as the first argument to the method. This method that is passed to array map will then be used to return a new value for every element in the array that it was called off of. The value for each element is passed as an argument for the method that is passed when calling array map, so the current value for each element can be used in the expressions and statements that are used to furnish a new value for each element in the array. Also it is important to note that it is indeed a new array that is returned, and the array that array map is called off of is not mutated in place. Many array prototype methods will mutate in place such as array sort, but this is not the case with array map, and certain other array prototype methods.

If you are still a little confused then maybe it would be best to just start working out a few simple examples. One good starting point would be just having a simple array of number primitives and then use array map to create a new array of powers using the numbers in the array as exponent value for the Math pow method.

2 — Doing the same thing with Array forEach, or while loops

If you are new to javaScript you might all ready be doing this sort of thing with other tools in the toolbox sort of speak. When it comes to the very basic example that I have covered so far it is not to hard to do the same thing with the array foreach method, or some kind of loop such as a while loop. The use of array foreach comes up all the time in from discussions and the like, and often more experienced javaScript developers shun the use of the array forEach method. I try to nt be so judgmental about the use of it, and I often fine myself using it on occasion still, but I am of course aware of the other options to use such as but certainly not limited to array map.

So the same thing that can be done with the array map method can be done with the array foreach method, and creating a new array, by dong something like this.

A while loop could also be used of course, or just about any other kind of loop for that matter to reproduce a similar effect to what can be obtained by using array map.

So it is not like the array map method is the only way to go about doing something like this. In fact in many situations I might prefer to go with a while loop because of the greater degree of flexibility that can be achieved. In addition I am not much of a performance nut, but from what I gathered while loops do tend to preform a little faster also for what that is worth. What I try to avoid is getting fixed on just one way to go about doing something, and thinking that this one way of doing it is the only true way of doing it. I see that all the time and I do not care to add to it. It is not to say that these ways of creating a new array based off of values from another array do not have there drawbacks compared to array map still so lets look at some more examples.

3 — forEach and chaining compared to array map.

So although the array foreach method can be used to do the same thing as array map by just creating a new array with the array bracket syntax and pushing in new values. There is one draw back that comes to mind right away when it comes to chaining. The problem can be resolved by bringing an IIFE into the mix, but I have to admit that it is making the code a little more complex compared to just using array map.

It might make sense to do something like this with a while loop though if I need to create a new array of values from a source array, but not all values in the array maybe. However the use of array forEach is not really such a great choice, because on one hand I can just use array map that is a little more appropriate here, and on the other hand I can use a while loop for better flexibility. However array forEach is is not really setting itself apart from the other two options, so often I use one of those over forEach.

4 — Using array map with a plain old object with the help of the Object values static method

So one draw back of the array map prototype method might be that is it an array prototype method so it can not be used out of the box with objects in general. This might be one of the talking points as to why the lodash map method has a little something more going on for itself compared to its native counterpart. However it is not to hard to overcome this issue by way of taking advantage of some more native methods to work with when it comes to just plain old javaScript by itself. If it is an array like object that you are working with than just using the function call prototype method will help to get map to work with it. When it comes to Objects in general there is the Object values and Object keys static method that can be used to create an array of values or key names from an Object.

5 — Using array map to copy an array of objects

Another taking point about the array map method is that it can often be used as a way to co about copying an array of objects. That is that the array map can be used as a way to create shallow, and event deep clones, or copies if you prefer of arrays. This is because as I have mentioned the array map method will return a new array rather than mutating the array that the method is called off of in place. So right off the bat the array map method will always be a good way to go about making shallow clones of arrays at least. However depending on what I do in the method that I use with array map, I can also create whole new objects when dealing with arrays of objects also so then array map can also be used as a way to create deep clones of objects also.

I will not be getting into detail about copying arrays here as that would be a bit off topic, but I have wrote a post on copying arrays that you might want to check out to read more about how to go about making clones of arrays.

6 — converting a string to an array and back again with array map and other options

In this section I will be going over some quick examples of breaking a string down into an array of characters, and then joining the array back into a string with some kind of separator between each character in the source string. Here I will be going over some examples that both do and do not use array map as a way to go over what there is to work with not just will array map, but with built in prototypes in general. That is that the array map method is an example of a method that is part of the array prototype object, and there are other methods to work with in that prototype object other then that of the array map method such as the array join method. In addition there are prototype objects with other built in classes of javaScript including the String and Function prototypes.

6.1 — using String.split and Array.join

When it comes to breaking down a string into an array of characters the first and for most method that might come to mind is the string split prototype method. By calling string split method the result is an array, at which point I can then use array prototype methods off of the resulting array such as the array join method that can be used to join the elements of an array back into a string.

Split and join are great basic tools, but they do have there limitations such as that I can not preform some kind of custom logic for each element in the resulting array.

6.2 — Using string split, array map, and array join.

After breaking a string down into an array with the string split method I am now dealing with an array rather than a string, so I can now use and array prototype method like array map. With array map I can now do whatever I want inside the body of the function that I use with array map such as using each letter in the source array to create a number using parseInt.

6.3 — Dropping string split and using function call, array map, and array join

Another prototype method that is worth mentioning in this section is the Function call method, by using that it is possible to drop the use of the string split method. The reason why that is is that they way that a string is structured it is all ready an array to begin with in a way in the sense that it can be worked with by way of numbered key values and a length property. The only problem really is that a String is of the String prototype rather than that of the Array prototype. So the function call method can be used to set the value of this for map to that of a string and then array map will work directly with a string rather than an array because a string is an example of an array like object.

7 — Sparse arrays and the array map method

One thing that is of concern when using the native array map method is what happens when the array map method is used with what is called a sparse array. That is an array where one or more of the index key values is not defined therefor the value of the key is undefined.

7.1 — Using array map with a sparse array

In this example I made a sparse array and then called the array map method off of the sparse array. The result is that the function that I gave to the array map method is only called for the single public key of the array.

7.2 — Custom array map method

One way to address this would be to not use the array map method but make a custom array map method that will call the given function for each index from zero to the length of the array minus one, rather than calling the function for every public key.

8 — Conclusion

So the array map method is one of several methods in the array prototype that have to do with creating an array from a source array. The array map method is a good choice if you want to created a new array from all elements in the array, but there are of course other options that a javaScript developer should be aware of, namely filter, and reduce, but also many other such as sort.

Definition and Usage

Sanje Qi

The map() method creates a new array with the results of calling a function for every array element.

The map() method calls the provided function once for each element in an array, in order.

Note: map() does not execute the function for array elements without values.

Note: this method does not change the original array.

Syntax

array.map(function(currentValue, index, arr), thisValue)

function(currentValue, index, arr)Required. A function to be run for each element in the array.
Function arguments:

  1. currentValueRequired. The value of the current element
  2. indexOptional. The array index of the current element
  3. arrOptional. The array object the current element belongs to
  4. thisValue . Optional. A value to be passed to the function to be used as its “this” value. If this parameter is empty, the value “undefined” will be passed as its “this” value

Intro

From the classic forloop to the forEach() method, various techniques and methods used to iterate through datasets abound JavaScript. However, one of the more popular methods is the .map() method.

.map() creates an array from calling a specific function on each item in the parent array. .map() is a non-mutating method in that it creates a new array as against mutating methods which only make changes to the calling array. This can be tricky to remember.

In this post, we’ll look at 4 noteworthy uses of the .map() in JavaScript. Let's begin!

Calling A Function on Each Item in an Array

.map() as earlier stated accepts a callback function as one of its arguments and an important parameter of that function is the current value of the item being processed by the function. This is a required parameter. With this parameter, we can modify each individual item in an array and create a new function off it. Here's an example:

This can even be simplified further to make it cleaner with:

Having code like sweetArray.map(makeSweeter) makes that a bit more readable when you jump into this code.

Converting a string to an Array

.map() is known to belong to the Array prototype. How about we use it to convert a String to an Array. Not to worry, we are not developing the method again to work for strings rather we will use the special .call() method.

Everything in JavaScript is an object and methods are just functions attached to these objects. .call() allows us to utilize the context of one object on another. Therefore, we would be copying the context of .map() in an array over to a string.

.call() can be passed arguments of, the context to be used, and "parameters for the arguments of the original function". Sounds like gibberish? Here's an example.

Here, we simply used the context of .map() on a String and passed an argument of the function which .map() expects. Voila! We have a wolf-lang looking characters in our console. Yikes!

This functions like the .split() method of a String only that each individual string characters can be modified before being returned in an array.

Rendering Lists in JavaScript Libraries

JavaScript libraries like React utilize .map() to render items in a list. This requires JSX syntax however as .map() method is wrapped in mustache-like JSX syntax. Here's a good example of a React component.

Are you unfamiliar with React? This is a simple stateless component in React which renders a div with a list. The individual list items are rendered using .map() to iterate over the names array initially created. This component is rendered using ReactDOM on the DOM element with id of root.

Reformatting Array Objects

How about handling objects in an array? .map() can be used to iterate through objects in an array and in a similar fashion to traditional arrays, *modify the content of each individual object *and return a new array. This modification is done based on what is returned in the callback function. Here's an example:

All we did is simply modify each object in the array using the bracket and dot notation. This use case can be employed to process or condense received data before being saved or parsed on a frontend application.

Conclusion

In this post, we looked at for main uses of the .map() method in JavaScript. A thing to note is that in combination with other methods, the functionality of .map() can be extended and utilized powerfully. Try to find out more use cases. Leave your comments, questions, and feedback in the comments section, they'll be appreciated!

Начало работы с методами JavaScript-массивов .map(), .filter() и .reduce()

Когда я разбирался в том, как пользоваться методами JS-массивов .map() , .filter() и .reduce() , всё, что я читал, смотрел и слушал, казалось мне очень сложным. Эти концепции рассматривались как некие самостоятельные механизмы, ни к чему другому отношения не имеющие. Мне тяжело было ухватить их суть и их понять.

Я слышал, что это — базовые вещи, понимание которых является чем-то вроде границы между «посвящёнными» и «непосвящёнными». Хотелось бы мне тогда, чтобы мне сказали о них правду. Она заключается в том, что эти три метода символизируют то, что причины, по которым перебирают некие итерируемые объекты, часто вписываются в одну из трёх функциональных категорий.

Просматривая код, который я писал раньше, я понял, что в 95% случаев, когда я перебирал элементы строк или массивов, я выполнял одно из следующих действий:

  • Применение к каждому значению некоей последовательности инструкций (аналог метода .map() ).
  • Фильтрация значений, соответствующих заданному критерию (то же, что делает .filter() ).
  • Сведение набора данных к единственному агрегированному значению (аналог .reduce() ).

Для того чтобы попрактиковаться, я взял свой старый код и отрефакторил его с использованием этих методов. Это оказалось весьма полезным занятием.

А теперь, без лишних слов, давайте поговорим об этих методах, и, в частности, посмотрим на то, как использовать их вместо широко распространённых схем применения циклов.

Метод .map()

Метод .map() используется в том случае, если нужно сделать следующее:

  1. Надо выполнить над каждым элементом итерируемого объекта некую последовательность действий.
  2. Надо вернуть значение, которое, предположительно, было изменено.

Вот как сделать то же самое с помощью .map() :

Тут используются довольно-таки лаконичные синтаксические конструкции. Поэтому давайте разберём этот пример. Метод .map() принимает коллбэк. Это — функция, которая будет применяться к элементам массива. В данном случае это — стрелочная функция, которая объявлена прямо в круглых скобках, следующих за объявлением метода.

Имя параметра price — это то имя, которое будет использоваться при работе с элементами массива. Так как наша стрелочная функция имеет всего один параметр — мы можем обойтись без круглых скобок при её объявлении.

Выражение после стрелки ( => ) — это тело коллбэка. Так как в теле функции имеется лишь одно выражение — мы можем обойтись без фигурных скобок и без ключевого слова return .

Если такая запись кажется вам непонятной — вот немного расширенный вариант этого примера:

Метод .filter()

Метод .filter() применяется в тех случаях, когда из итерируемого объекта нужно выбрать некие элементы. При использовании этого метода нужно помнить о том, что значения, соответствующие фильтру, включаются в итоговый результат, а не исключаются из него. То есть — всё, для чего функция, переданная .filter() , возвратит true , будет оставлено.

Рассмотрим пример, в котором нужно отобрать из массива целых чисел только нечётные элементы. Здесь мы воспользуемся оператором взятия остатка от деления и будем выяснять — имеется ли остаток от деления каждого элемента массива на 2. Если остаток равен 1 — это говорит нам о том, что соответствующее число является нечётным. Сначала взглянем на способ решения этой задачи с помощью обычного цикла:

Метод .filter() , как и .map() , принимает один коллбэк, которому будут поочерёдно передаваться элементы итерируемого объекта:

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

Метод .reduce()

И вот мы, наконец, добрались до метода .reduce() . Он, полагаю, самый непонятный из трёх рассматриваемых сегодня методов. Имя этого метода намекает на то, что он используется для сведения нескольких значений к одному. Однако мне кажется, что легче размышлять о нём как о методе, который позволяет собирать некие значения из частей, а не как о методе, который позволяет что-то «сворачивать» или «редуцировать».

При конструировании кода, в котором вызывается этот метод, сначала задают некое начальное значение. По мере того, как метод перебирает значения массива, это начальное значение модифицируется и, в изменённом виде, передаётся в следующую итерацию.

Вот классическая задача, для решения которой нужно вычислить сумму элементов массива. В нашем случае она заключается в поиске суммы пожертвований на некий благотворительный проект:

В отличие от методов .map() и .filter() , метод .reduce() нуждается в коллбэке, принимающем два параметра. Это — аккумулятор и текущее значение. Аккумулятор — это первый параметр. Именно он модифицируется на каждой итерации и передаётся в следующую:

Методу .reduce() тоже можно передать второй аргумент. Это — то, что будет играть роль начального значения для аккумулятора. Предположим, мы хотим узнать общую сумму пожертвований за два дня, учитывая то, что вчера эта сумма составила $450, а сведения о сегодняшних пожертвованиях хранятся в массиве:

Итоги

Надеюсь, теперь вы разобрались с методами JS-массивов .map() , .filter() и .reduce() . Воспринимайте их как механизмы, улучшающие читабельность вашего кода. Они позволяют писать более компактные программы, чем те, которые получаются при использовании обычных циклов. Но самая главная их сильная сторона заключается в том, что они позволяют ясно выразить намерение, которое лежит в основе кода.

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

Уважаемые читатели! Пользуетесь ли вы методами JS-массивов .map(), .filter() и .reduce()?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *