Итак, для тех, кто не слышал о методе reduce() в Javascript, это обязательный метод при работе с массивами.

Конечно, вы можете полностью игнорировать эту красивую и мощную функцию массива и придерживаться классического цикла for или while. Ничего страшного, если вы не знаете (или не хотите использовать) этот reduce() . Но с reduce() у нас может быть более короткий/чистый код в большинстве случаев, когда вы хотите вычислить или преобразовать что-то из заданного массива. Кроме того, иногда вы также можете украсть драгоценное время у своих коллег, когда они начнут смотреть на ваш «грязный и мистический» фрагмент кода (LOL).

Хватит болтовни. Давайте сразу перейдем к примеру с массивом reduce . Начнем с простого: суммируем элементы в массиве чисел.

const arr = [2, 5, 8, 9]
// "Classical" way
let result = 0
for (const x of arr) {
    result += x
}
console.log(result)
// "Thug-Pro" way
const result = arr.reduce((prev, curr) => prev + curr, 0)
console.log(result) // 24

Совет. Вы можете сразу попробовать это в Dev Console в браузере (нажав F12 и выбрав вкладку Console).

Теперь позвольте мне разбить наш предыдущий код на более мелкие, более простые для понимания части, чтобы увидеть, что, черт возьми, здесь происходит.

Во-первых, если мы посмотрим на его документацию, метод Array reduce() принимает два аргумента:

  • Первый: функция обратного вызова
  • Второй (необязательно): начальное значение

Второй аргумент довольно очевиден. Это просто начальное значение для нашего расчета. В приведенном выше примере начальное значение равно 0.

Давайте сосредоточимся на первом аргументе. Сначала это может показаться ошеломляющим, но если мы заметим, это просто функция, которая возвращает значение. Я могу переписать предыдущий код в стиле ES6, как показано ниже:

const arr = [2, 5, 8, 9]
// More verbose way
function accumulativeFunc(previous, current) {
    return previous + current
}
const result = arr.reduce(accumulativeFunc, 0)
console.log(result) // 24

И вот как это работает:

  • Во-первых, он будет перебирать каждый элемент в данном массиве. Как я уже говорил, метод reduce был создан для «вычисления или преобразования чего-либо из заданного массива». Тогда ему нужна отправная точка. Вот как приходит 0.
  • Затем функция обратного вызова выполняется с previous = 0 и current = 2. Таким образом, первое вычисление 0 + 2 . Результат этого вычисления будет сохранен и передан в аргумент previous в следующем цикле.
  • Процесс повторяется до тех пор, пока не будут перебраны все элементы массива.

Мы можем шаг за шагом представить процесс следующим образом:

// Step 1: "previous" is assigned the initial value of 0
previous = 0
// Step 2 (current = 2): calculate 0 + 2, then assign to "previous"
0 + 2 = 2
previous = 2
// Step 3 (current = 5): calculate 2 + 5, then assign to "previous"
2 + 5 = 7
previous = 7
// Step 4(current = 8): calculate 7 + 8, then assign to "previous"
7 + 8 = 15
previous = 15
// Step 5(current = 9): calculate 15 + 9, then assign to "previous"
15 + 9 = 24
// Step 6: The loop ends, the "reduce" method now returns the result
result = 24

Достаточно легко, верно?

Важно отметить, что есть две дополнительные вещи, которые я не упомянул ранее для простоты:

  • Во-первых, накопительная функция (или accummulativeFunc в данном случае) на самом деле принимает максимум четыре аргумента. Это previous (или накопительное значение), current (значение обрабатываемого элемента), index (индекс обрабатываемого элемента) и, наконец, array (сам массив). Последние два аргумента являются необязательными, поэтому мы просто включаем их на случай, если они нам понадобятся.
  • И второе, мы можем опустить начальное значение 0, потому что оно необязательное и в данном случае не влияет на результат. Но в некоторых других ситуациях нам нужно указать это значение. Если этого не сделать, то в качестве начального значения будет взят первый элемент массива. Это может привести к нежелательному поведению, например:
    [{ v: 2 }, { v: 5 }].reduce((prev, curr) => prev + curr.v) вернет [object Object]5 , хотя вы ожидаете, что будет 7 .

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

Если вы хотите узнать больше о редукции, я настоятельно рекомендую MDN-Webdocs. Там вы сами можете узнать еще много всего интересного. Это действительно хороший ресурс знаний для веб-разработчиков.

Удачного кодирования и следите за обновлениями!