Массивы очень часто используются в мире программирования. В JavaScript существует несколько методов итератора массива. Метод filter() удобен для поиска элементов в массиве, удовлетворяющих определенному условию. Метод map() применяет функцию к каждому элементу и некоторым образом изменяет его. Метод, который мы рассмотрим сегодня, — это метод reduce(). Этот метод удобен в сценариях, когда вы хотите создать одно агрегированное значение. Вы уменьшаете массив до одного значения.

Метод reduce() — это встроенный в JavaScript метод, используемый для перебора массива, чтобы суммировать его в одно значение.

Давайте рассмотрим пример без использования метода reduce(), но с использованием цикла for.

Допустим, вам дан массив чисел:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

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

1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55

Стандартный способ справиться с этой проблемой состоит в том, чтобы сначала объявить новую переменную: аккумулятор и установить ее значение равным 0. После этого мы перебираем массив, добавляя элементы в аккумулятор. После каждой итерации значение аккумулятора увеличивается на значение текущего элемента, по которому выполняется итерация. Наконец, когда цикл завершается, мы возвращаем накопленное значение.

Вот пример кода для этой проблемы:

function sum (numbers) {
// declare a new var and set it to 0
let accumulator = 0;
// iterate over an array
for (var i = 0; i < numbers.length; i++) {
// add the current element of the array to that new var till the end of loop 
accumulator = accumulator + numbers[i];
    }
// return this accumulated value
return accumulator;
}

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9 , 10];
let total = sum (numbers);
console.log(total);// output -> 55

Этот метод с использованием цикла for работает. Тем не менее, это очень просто и специфично для этой ситуации. Вот почему полезен метод reduce(). Метод reduce() используется, когда мы хотим получить некоторую информацию от каждого элемента в коллекции и собрать эту информацию в окончательное итоговое значение.

Функция reduce() принимает 4 аргумента:

  1. Аккумулятор
  2. Текущая стоимость
  3. Текущий индекс
  4. Исходный массив

Вот пример кода, показывающий, как выглядит метод reduce() со стрелкой, обратным вызовом и встроенными функциями обратного вызова:

// Arrow function
reduce((accumulator, currentValue) => { ... } )
reduce((accumulator, currentValue, index) => { ... } )
reduce((accumulator, currentValue, index, array) => { ... } )
reduce((accumulator, currentValue, index, array) => { ... }, initialValue)

// Callback function
reduce(callbackFn)
reduce(callbackFn, initialValue)

// Inline callback function
reduce(function callbackFn(accumulator, currentValue) { ... })
reduce(function callbackFn(accumulator, currentValue, index) { ... })
reduce(function callbackFn(accumulator, currentValue, index, array){ ... })
reduce(function callbackFn(accumulator, currentValue, index, array) { ... }, initialValue)

Чтобы решить проблему перед использованием метода reduce(), вместо использования цикла for это будет выглядеть так:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const reducerFunction = (accumulator, currentValue) => accumulator + currentValue;
const total = numbers.reduce(reducerFunction)
console.log(total); // output -> 55

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

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const total = numbers.reduce ((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(total); // output -> 55

Нам не нужно использовать функцию стрелки. Мы могли бы также использовать встроенную функцию обратного вызова:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const total = numbers.reduce (function (accumulator, currentValue) {return accumulator + currentValue}, 0);
console.log(total);// output -> 55

Другой пример:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const total  = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
console.log(total) //output -> 55

Когда мы используем метод reduce() для нашего массива numbers, мы передаем ему два аргумента: функцию обратного вызова, определенную как выражение функции стрелки, в данном случае (accumulator, currentValue) => accumulator + currentValue и необязательное начальное значение или аккумулятор, установленный в 0 в этом случае. Затем метод выполняет функцию обратного вызова для каждого элемента массива (1, 2, 3, … 10), каждый раз передавая текущее значение аккумулятора и текущий элемент. После каждой итерации функция обратного вызова обновляет значение аккумулятора, и это обновленное значение аккумулятора затем передается в качестве первого аргумента функции обратного вызова. Это повторяется до конца массива. Когда в массиве нечего перебирать, возвращается окончательное значение аккумулятора.

Начальное значение инициализации является необязательным, но в некоторых случаях его отсутствие может привести к проблемам. Если начальное начальное значение отсутствует, то в качестве начального значения используется первый элемент массива.

В заключение, метод reduce() отлично подходит для использования, когда мы хотим получить одно единственное значение из массива. При использовании метода reduce() нужно помнить 3 основных момента:

  1. массив, который мы хотим уменьшить
  2. функция обратного вызова, которая определяет, как вы хотите манипулировать массивом
  3. начальное стартовое значение аккумулятора

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