map и reduce в JS

map и reduce в JS

Vitaliy Emeliyantsev

Сегодня покажу, как применять функции map и reduce в JS на практике.


Возьмем задачу:

1. На странице есть несколько форм с селектами;

2. В каждом селекте можно выбирать числа (1, 2, 3, например);

3. Выбранные в селектах числа в пределах каждой формы нужно перемножить между собой.

Наш своеобразный калькулятор


С чего начать? Сперва опишем схему словами:


1. Проходим по каждой форме в цикле;

2. В каждой форме проходим по каждому селекту в цикле;

3. Собираем их значения;

4. Перемножаем их (в пределах одной формы);

5. В конце выдаем результат - массив чисел, по одному с каждой формы.


Циклы, это вроде бы each, while, repeat. Но помимо хождения по циклам нам нужно еще и собирать оттуда данные. В голове всплывают жуткие конструкции вида:

a = 0
elements.each { a = a + element.value }
return a


Брр. Используем вместо этого map и reduce:

map - трансформирует одни значения в массиве в другие.

Например, было [1, 2, 3] - стало [-1, -2, -3] (внутри map каждое значение умножили на минус единицу).

reduce - позволяет получать агрегированные значения из массивов (суммы, произведения).

Например, было [1, 2] - стало 3 (внутри reduce просуммировали значения массива).


В итоге для нашего калькулятора получаем такой код (с jquery):

array = $('.form').map(function() {
 return $(this).find('.select')
        .map(function() { return $(this).val() || 1; })
             .get()
             .reduce(function(a, b) { return a * b; });
}).get();


По шагам:

1. $('.form') - дает нам массив форм на странице;

2. Функцией map превратим массив форм в массив произведений значений селектов;

3. Значит внутри map мы вычислим произведение значений селектов в каждой форме;

4. Внутри map, this ссылается на текущую форму в цикле. От нее мы отталкиваемся и находим все селекты через find('select');

5. find('.select') - дает нам массив селектов. Применяем к нему map, чтобы получить из него массив значений с этих селектов (и потом их перемножить);

6. При этом если вдруг в селекте еще не выбрано никакое значение - используем значение 1. Тогда наше перемножение не сломается из-за того, что некоторые значения селектов еще не определены;

7. Получив массив значений, перемножаем их через reduce, и получаем внутри каждой формы одно число - перемноженные значения всех селектов формы;

8. Эти числа формируют в конечном итоге массив перемноженных значений селектов с каждой формы.


Смотреть пример на jsfiddle


Полезный пост? Делитесь им в чатах, отправляйте коллегам, и подписывайтесь на канал @gambala_live - будет еще много интересного.

Report Page