Продвинутое использование метода reduce
Перевод статьи How to reduce() arrays от jstips.co с небольшими дополнениями.
Метод массивов reduce
не похож на другие перебирающие методы массивов: результатом его выполнения может быть значение любого типа данных, которое задаёте сами. Именно такая особенность может сделать reduce
чрезвычайно мощным инструментом в руках опытного разработчика.
Обычное использование
Обычно reduce
используется для работы с числами и строками и позволяет проводить “аккумуляцию” значений. Пример использования уже успевший стать классическим:
Принцип работы
Reduce
принимает два аргумента: callback
функцию и начальное значение, которое будет присвоено аргументу result
в примере выше при первой итерации. callback
функция принимает целых 4 аргумента: промежуточное значение (аргумент result
в примере выше), элемент массива, индекс элемента и сам массив. После каждой итерации в промежуточное значение записываются новые данные, которые берутся из результата выполнения функции callback
при прошлой итерации:
Разумеется, reduce
может работать с любыми типами данных, не только с числами. Пример со строками (в данном случае в качестве начального значения стоит передавать пустую строку):
Продвинутое использование
Пример более продвинутого использования reduce
был подсмотрен у Redux.
Представьте, что у вас есть каталог товаров, у каждого из которых есть определённый набор свойств, в том числе и свойство price
, которое и возьмём для примера. Ваш покупатель выбирает товары и добавляет их в корзину. Таким образом, заходя в корзину, пользователь остаётся с выбранными им товарами, которые мы, как разработчики, будем считать массивом объектов подобного вида:
Отлично! Уже сейчас мы можем вычислить общую стоимость товаров и выставить покупателю счёт. Или нет? Магазин у вас интернациональный и каждый клиент вправе выбрать ту валюту, с помощью которой ему будет удобно рассчитаться. Чтобы удобно всё это оформить создадим объект функций “редюсеров”, которые будут вычислять стоимость, исходя из курса рубля:
Получая массив с ценами товаров, мы хотим рассчитать общую цену для каждого типа валюты и на выходе получить объект вида:
Чтобы получить возможность автоматически использовать все запрашиваемые callback
функции из объекта редюсеров нужно написать ещё одну функцию-обёртку, которая будет вычислять все переданные ей значения цен, последовательно вызывая функцию-редюсер для каждого типа валют:
И это всё, что нам было необходимо сделать. Теперь можем посмотреть, как это всё будет работать:
Подробнее о других методах работы с массивами (map, filter, forEach, some, every), а также о том, как они работают, вы можете узнать в этой статье.
Комментарии