Уеб уроци и ресурси по HTML,
CSS, CSS3, JavaScript и други

Обхождане на масив с map() 1

Сподели урока

В предишния урок разгледах как работи метода forEach(), който се използва за обхождане на масив. В този урок ще разгледам друг метод - map(), който също се използва за обхождане на масив. Каква ли е разликата между тях?

Тъй като често ми се налага да използвам map(), днес ще отделя няколко минути, за да си припомня как точно работи.

Синтаксис

Синтаксиса на map() изглежда така:

arrayName.map(function(element, index, array) {
  // „Тяло” на функцията
}, thisArg);

arrayName е името на масива, който искам да обходя.

map() преминава през всеки елемент от масива във възходящ ред като изпълнява callback функция за всеки от тях. Тя приема три параметъра:

  • element - настоящия елемент от масива
  • index - индекса, на който се намира настоящия елемент
  • array - масива, върху който прилагаме map()

thisArg е втори, незадължителен параметър, който определя стойността на this в callback функцията.

map() е част от Array обекта в JavaScript.

Въпреки очевидната прилика с forEach(), този метод работи по малко по-различен начин.

forEach() обхожда даден масив като изпълнява callback функция за всеки елемент от него. Това е всичко. Звучи като доста монотонна работа. Скука!

map(), от друга страна, освен че обхожда масива, ни връща бонус - нов масив, който е резултат от изпълнението на callback функцията за всеки елемент от първоначалния масив. Йей! :)

Звучи ми объркващо! Трябва да разгледам няколко прости примера, за да го разбера.

За да съпоставя работата на forEach() и map(), ще използвам същите два примера, които разгледах в урока за forEach().

Първи пример

Разполагам с масив от числа и искам да разбера на колко е равен квадрата на всяко едно от тях.

Използвайки map() това би изглеждало така:

[4, 12, 27, 14].map(function(number) {
  console.log(number + " на квадрат е " + number * number);
});

Принтиране на резултата в конзолата

Хм, това определено ми дава правилен резултат, но къде е новият масив, който трябваше да получа?

Така погледнато, примерът по-горе не представя правилно работата на map(). Наистина, кода се изпълнява без грешка, но самата идея за използване на map() е различна.

Идеята е, че разполагам с определен масив и искам, базирайки се на него, да създам нов масив, който ще използвам по-късно в своя код.

Ако искам просто да обходя определен масив, без да връщам нищо от него, forEach() би ми свършил чудесна работа.

Погледнато от този ъгъл, примера по-горе ще стане:

var numbers = [4, 12, 27, 14];
var squares = numbers.map(function(number) {
  return (number + " на квадрат е " + number * number);
});
console.log(numbers);
console.log(squares);

Принтиране на резултата в конзолата

Нещата започват да се изясняват.

numbers е първоначалния масив. squares е новия масив. Забелязвам също, че map() не промени (мутира) елементите на обхождания масив. Това е важно!

Виждам и един доста съмнителен return! Той ми е нужен, за да върна стойността, която искам да запазя в новия масив. Ако го пропусна, map(), понеже е супер любезен метод, все пак ще ми върне нов масив, но всеки елемент от него ще има стойност undefined.

Доказателство:

var numbers = [4, 12, 27, 14];
var squares = numbers.map(function(number) {
  number + " на квадрат е " + number * number;
});
console.log(squares);

Принтиране на резултата в конзолата

Втори пример

Да предположим, че получавам задачка да създам функция, която приема масив с обекти, извършва някаква „магия” и връща определена информация. Всеки обект представлява отделна книга, която има свойства като ISBN номер, заглавие, автор и цена. Резултатът, който трябва да върна от тази функция, е нов масив, който съдържа единствено заглавията на книгите.

Масива, с който трябва да работя, изглежда така:

var books = [
  {isbn: 0596517742, title: "JavaScript: The Good Parts", author: "Douglas Crockford", price: 13.57},
  {isbn: 1593275846, title: "Eloquent JavaScript: A Modern Introduction to Programming", author: "Marijn Haverbeke", price: 17.00},
  {isbn: 0596806752, title: "JavaScript Patterns", author: "Stoyan Stefanov", price: 12.67}
];

Резултатът трябва да бъде следния:

["JavaScript: The Good Parts", "Eloquent JavaScript: A Modern Introduction to Programming", "JavaScript Patterns"];

Това условие ми звучи като идеален кандидат за map()!

Ето моето решение:

// Същия масив, който представих по-горе. 
// Тук го пропускам, за да направя кода по-кратък
var books = [...];

var titles = books.map(function(book) {
  return book.title;
});

// Принтиране на резултата в конзолата
console.log(titles);

Принтиране на резултата в конзолата

Сравнявайки този код с кода, който използвах в урока за forEach(), забелязвам че тук съм значително по-ефективен, защото използвам по-малко код за постигане на същия резултат.

Кратко обяснение

В titles запазвам новият масив, който се връща след извикване на map().

callback функцията на map() приема три аргумента. На мен ми е нужен само първия. Наименувам го book.

return book.title; връща единствено стойността на свойството title.

Чрез console.log(titles); принтирам съдържанието на titles в конзолата, за да проверя дали резутата наистина е този, който очаквам в действителност.

Това е така. :)

Заключение

В този урок разгледах работата на map(). Двата примера показват само малка част от ситуациите, в които този метод може да бъде полезен. Препоръчвам ти да сравниш кода в примерите от този урок с примерите от урока за forEach(), за да откриеш разликата между тези два метода. Линковете по-долу ще те отведат до още полезна информация.

На мен лично ми беше от полза да си припомня всичко това. Надявам се, че ти също научи нещо ново. Не спирай да се учиш!

Допълнителна информация

Снимка от Jackie Nell.

Поздравления, това е краят на този урок!
За награда получаваш вкусен мъфин.

Награда за това, че успя да достигнеш до края на урока.

Хареса ли ти урока? Сподели го със света :)

Начало

1 страхотен коментар

  1. 1

    Desislava Vladimirova
    03 май 2017 12:19

    Много благодаря за страхотния урок!

    Всичко е представено по начин разбираем за напълно начинаеща, каквато съм аз. Много благодаря! Надявам се да има още подобни уроци...моля..