Найти в Дзене
Работяги

map, filter, reduce - три всадника функционального апокалипсиса в JS - часть 3 - reduce

Привет, я Дмитрий Канаев, Backend NodeJS разработчик, представляю IT сообщество Работяги. В этом сообществе ты можешь поделиться своими проблемами в разработке и найти ответы на интересующие тебя вопросы из сферы IT. Ссылки на наши другие ресурсы вы можете найти в профиле нашего канала или в конце этой статьи.

Сегодня мы завершаем цикл статей, в которых мы рассматривали три важных функциональных «столпа» в JavaScript.

Ссылка на первую часть цикла – https://dzen.ru/a/ZcpVvSfcYBZn8YyK

Ссылка на вторую часть цикла – https://dzen.ru/a/Zd0Lxlo4KDs2uY2x

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

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

Операция reduce реализуется в виде функции высшего порядка, сводящей массив элементов к единственному значению. Это значение вычисляется из накапливаемого результата вызова функции для каждого элемента массива, которой передается в качестве параметра значение аккумулятора.

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

reduce(f, [e0,e1,e2,e3],accum) -> f(f(f(f(accum, e0), e1), e2), e3) -> R

Рассмотрим упрощенную реализацию внутреннего механизма выполнения операции reduce:

-2

Функции, реализующей операцию reduce, передаются следующие параметры:

arr – исходная коллекция элементов.

fn – функция-итератор, вызываемая для каждого элемента массива, которой в качестве параметров передаются: накапливаемое значение, текущее значение в массиве, индекс массива и сам массив.

accumulator – начальное значение аккумулятора, которое используется затем для хранения накапливаемого результата и передается при каждом последующем вызове функции.

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

reduceRight в данном случае – это функция аналогичная функции reduce, только аргументы итерируемой коллекции в данном случае будут передаваться функции-итератору не от первого к последнему, а наоборот – от последнего к первому.

Ссылки на наши ресурсы – ниже:

https://discord.gg/dWMKzXyG

https://t.me/podcust_rabot9g

https://www.youtube.com/@Rabot9gi

https://vk.com/club224443714