Прежде всего, название «reduce» на самом деле ничего не уменьшает. Это запутанное/хитрое соглашение об именовании, которое часто встречается в программировании. Хотя для лучшего понимания вы можете считать, что reduce принимает множество значений, сводит их в одно значение и возвращает.
reduce — это функция более высокого порядка, которая принимает два аргумента:
- функция обратного вызова и
- исходное значение.
А функция обратного вызова принимает четыре аргумента:
- previousValue,
- currentValue,
- currentIndex,
- массив
Чаще можно встретить ситуацию, когда функция обратного вызова принимает только два аргумента в зависимости от проблемы, которую нам нужно решить, что является Ок.
[1, 2, 3].reduce((previousValue, currentValue, currentIndex, array) => {
// here the return statement goes...
}, initialValue);
Теперь давайте рассмотрим практический пример. Напишите программу, которая возвращает сумму всех элементов массива. Пожалуйста, сначала подумайте как обычно, а затем мы решим то же самое с помощью reduce. Вот обычный способ/процедура написания этой программы:
function sum(arr) {
let sum = 0;
for(let i = 0; i < array.length; i++) {
sum = sum + arr[i];
}
return sum;
}
Итак, если мы вызовем sum с массивом, то он вернет сумму всех его элементов. Правильно?
Да, и то же самое мы можем сделать с reduce. Вот код:
[1, 2, 3, 4].reduce(function(previousValue, currentValue) {
let result = previousValue + currentValue;
return result;
}, 0);
Это делает то же самое. Редуктор проходит по элементам массива, на каждом шаге добавляя текущее значение массива к результату предыдущего шага (этот результат является текущей суммой всех предыдущих шагов) — пока не останется больше элементов для добавления.(ссылка: здесь)
Здесь previousValue
— обычная sum
, а currentValue
— обычная arr[i]
.
В первой итерации нет previousValue (возвращаемое значение предыдущего вычисления)
— верно? В этом случае initialValue
будет использоваться как previousValue
. Если initialValue
отсутствует, то в качестве начального значения используется элемент массива с индексом 0, и итерация начинается со следующего элемента (индекс 1 вместо индекса 0).
Вместо того чтобы использовать дополнительную переменную result, вы можете написать программу следующим образом:
[1, 2, 3, 4].reduce(function(previousValue, currentValue) {
previousValue += currentValue;
return previousValue;
}, 0);
И еще короче:
[1, 2, 3, 4].reduce((previousValue, currentValue) => previousValue += currentValue, 0);
Надеюсь, вы поняли. Теперь ваша задача написать программу, которая будет находить минимальное число из непустого массива с помощью reduce (считайте, что все элементы в массиве положительные).
Вот она:
const arr = [4, 2, 3, 1];
let result = arr.reduce((minValue, currentValue) => {
if (currentValue < minValue) {
minValue = currentValue;
}
return minValue;
}); // no initial value 😎
console.log(result);
❤️ Happy Coding ❤️