По моим собственным словам, reduce — это метод массива, который используется для «сведения» всех значений в массиве к одному значению. Отличным примером этого является суммирование всех чисел в массиве.

Вот более официальное определение reduce:

Метод reduce() выполняет функцию reducer (предоставленную вами) для каждого элемента массива, в результате чего получается одно выходное значение. — МДН

Итак, если у нас есть какой-то массив arr, мы можем вызвать для него reduce и передать функцию callback, которая будет выполняться для каждого элемента в массиве и будет возвращать одно значение result:

const result = arr.reduce(callback)

При желании вы можете передать начальное значение initialVal в reduce. Если начальное значение не передается, в качестве начального значения используется первый элемент массива.

const result = arr.reduce(callback, initialVal)

Функция обратного вызова принимает 4 аргумента:

  • accumulator — это накопление возвращаемых значений обратного вызова
  • currentVal — текущее обрабатываемое значение
  • index — текущий индекс обрабатываемого значения (необязательно)
  • arr — это массив, к которому был вызван reduce (необязательно)

Давайте посмотрим на пример, использующий преобразование в сумму чисел в массиве:

const arr = [1,2,3,4]
const result = arr.reduce((accumulator, currVal) => accumulator + currVal)
console.log(result)
// => 10

Здесь мы вызываем reduce для массива arr, мы используем функцию обратного вызова (accumulator, currVal) => accumulator + currVal и используем начальное значение по умолчанию. Наша функция обратного вызова добавляет каждый элемент (currVal) к нашей текущей сумме (accumulator).

Давайте рассмотрим, как именно это работает:

  • Поскольку мы не передали initialVal, первый элемент массива используется как initialVal и не используется в функции обратного вызова. Итак, наше accumulator начинается с 1
  • Первое значение, проходящее через функцию обратного вызова, равно 2, и с нашим accumulator равным 1, 1+2=3, поэтому наше accumulator теперь равно 3.
  • Следующее значение равно 3, 3+3=6, поэтому наше accumulator теперь равно 6.
  • И, наконец, наше последнее значение равно 4, 6+4=10, поэтому наше accumulator равно 10.
  • Мы возвращаем 10 из reduce, и 10 сохраняется в переменной result.

Если для вас это звучит очень похоже на этот код, вы не ошиблись:

const arr = [1,2,3,4]
let sum = 0
for (let i=0; i<arr.length; i++) {
    sum += arr[i]
}
console.log(sum)
// => 10

Цикл for также выполняет суммирование значений в массиве, reduce — это, пожалуй, более простой и чистый способ сделать это.

Если мы посмотрим на тот же пример, но включим initialVal из 5:

const arr = [1,2,3,4]
const result = arr.reduce((accumulator, currVal) => accumulator + currVal, 5)
console.log(result)
// => 15

Мы получаем тот же результат, что и выше, плюс 5. Это потому, что происходит та же логика, мы просто начинаем accumulator с 5 вместо первого значения в массиве.

Вы можете сделать гораздо больше с reduce, чем с суммированием чисел, и вот пример, демонстрирующий другой вариант использования:

const arr = ['cookie', 'cake', 'ice cream', 'cookie', 'brownie', 'cookie', 'ice cream', 'fruit', 'ice cream', 'cookie', 'cake']
const obj = arr.reduce((accumulator, currVal) => {
    if (accumulator.hasOwnProperty(currVal)) {
        accumulator[currVal]++
    }
    else {
        accumulator[currVal] = 1
    }
    return accumulator
}, {})
console.log(obj)
// => { 'cookie': 4, 'cake': 2, 'ice cream': 3, 'brownie': 1, 'fruit': 1 }

Мы только что использовали reduce, чтобы подсчитать, сколько раз каждый элемент появляется в массиве! Разберем приведенный выше код:

  • Мы передали пустой объект {} в качестве начального значения.
  • Для каждого элемента в массиве проверьте, является ли этот элемент ключом в нашем объекте, используя hasOwnProperty
  • Если это так, увеличьте значение, которое является подсчетом того, сколько раз оно находится в массиве.
  • Если это не так, добавьте элемент в качестве ключа к объекту и установите значение 1
  • После того, как мы просмотрим каждый элемент массива, верните accumulator и сохраните его в переменной obj.

Удачного сокращения!

Источники