Сводка
Метод reduce() применяет функцию к аккумулятору и каждому значению массива (слева-направо), сводя его к одному значению.
Синтаксис
arr.reduce(callback[, initialValue])
Параметры
callback- Функция, выполняющаяся для каждого элемента массива, принимает четыре аргумента:
previousValue- Значение, возвращённое предыдущим выполнением функции
callback, либо значениеinitialValue, если оно предоставлено (смотрите пояснения ниже). currentValue- Текущий обрабатываемый элемент массива.
index- Индекс текущего обрабатываемого элемента массива.
array- Массив, для которого была вызвана функция
reduce.
initialValue- Необязательный параметр. Объект, используемый в качестве первого аргумента при первом вызове функции
callback.
Описание
Метод reduce() выполняет функцию callback один раз для каждого элемента, присутствующего в массиве, за исключением пустот, принимая четыре аргумента: начальное значение (или значение от предыдущего вызова callback), значение текущего элемента, текущий индекс и массив, по которому происходит итерация.
При первом вызове функции, параметры previousValue и currentValue могут принимать одно из двух значений. Если при вызове reduce() передан аргумент initialValue, то значение previousValue будет равным значению initialValue, а значение currentValue будет равным первому значению в массиве. Если аргумент initialValue не задан, то значение previousValue будет равным первому значению в массиве, а значение currentValue будет равным второму значению в массиве.
Если массив пустой и аргумент initialValue не указан, будет брошено исключение TypeError. Если массив состоит только из одного элемента (независимо от его положения в массиве) и аргумент initialValue не указан, или если аргумент initialValue указан, но массив пустой, то будет возвращено одно это значение, без вызова функции callback.
Предположим, что reduce() используется следующим образом:
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
});
Функция обратного вызова будет вызвана четыре раза, аргументы и возвращаемое значение при каждом вызове будут следующими:
previousValue |
currentValue |
index |
array |
возвращаемое значение | |
|---|---|---|---|---|---|
| первый вызов | 0 |
1 |
1 |
[0, 1, 2, 3, 4] |
1 |
| второй вызов | 1 |
2 |
2 |
[0, 1, 2, 3, 4] |
3 |
| третий вызов | 3 |
3 |
3 |
[0, 1, 2, 3, 4] |
6 |
| четвёртый вызов | 6 |
4 |
4 |
[0, 1, 2, 3, 4] |
10 |
Значение, возвращённое методом reduce() будет равным последнему результату выполнения функции обратного вызова (10).
Если же вы зададите начальное значение initialValue, результат будет выглядеть так:
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
}, 10);
previousValue |
currentValue |
index |
array |
возвращаемое значение | |
|---|---|---|---|---|---|
| первый вызов | 10 |
0 |
0 |
[0, 1, 2, 3, 4] |
10 |
| второй вызов | 10 |
1 |
1 |
[0, 1, 2, 3, 4] |
11 |
| третий вызов | 11 |
2 |
2 |
[0, 1, 2, 3, 4] |
13 |
| четвёртый вызов | 13 |
3 |
3 |
[0, 1, 2, 3, 4] |
16 |
| пятый вызов | 16 |
4 |
4 |
[0, 1, 2, 3, 4] |
20 |
Значение, возвращённое методом reduce() на этот раз, конечно же, будет равным 20.
Примеры
Пример: суммирование всех значений в массиве
var total = [0, 1, 2, 3].reduce(function(a, b) {
return a + b;
});
// total == 6
Пример: разворачивание массива массивов
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
});
// flattened равен [0, 1, 2, 3, 4, 5]
Пример: склеивание массивов, содержащихся в объектах массива, с использованием оператора расширения и initialValue
// friends - список из объектов(друзей)
// где поле "books" - список любимых книг друга
var friends = [
{ name: "Anna", books: ["Bible", "Harry Potter"], age: 21 },
{ name: "Bob", books: ["War and peace", "Romeo and Juliet"], age: 26 },
{ name: "Alice", books: ["The Lord of the Rings", "The Shining"], age: 18 }
]
// allbooks - список, который будет содержать все книги друзей +
// дополнительный список указанный в initialValue
var allbooks = friends.reduce(function(prev, curr) {
return [...prev, ...curr.books];
}, ["Alphabet"]);
// allbooks = ["Alphabet", "Bible", "Harry Potter", "War and peace",
// "Romeo and Juliet", "The Lord of the Rings", "The Shining"]
Полифилл
Метод Array.prototype.reduce() был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать reduce() в реализациях, которые не поддерживают этот метод.
// Шаги алгоритма ECMA-262, 5-е издание, 15.4.4.21
// Ссылка (en): https://es5.github.io/#x15.4.4.21
// Ссылка (ru): https://es5.javascript.ru/x15.4.html#x15.4.4.21
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback/*, initialValue*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = 0, value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && ! (k in t)) {
k++;
}
if (k >= len) {
throw new TypeError('Reduce of empty array with no initial value');
}
value = t[k++];
}
for (; k < len; k++) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
Спецификации
| Спецификация | Статус | Комментарии |
|---|---|---|
| ECMAScript 5.1 (ECMA-262) Определение 'Array.prototype.reduce' в этой спецификации. |
Стандарт | Изначальное определение. Реализована в JavaScript 1.8. |
| ECMAScript 2015 (6th Edition, ECMA-262) Определение 'Array.prototype.reduce' в этой спецификации. |
Стандарт |
Совместимость с браузерами
| Возможность | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Базовая поддержка | (Да) | 3.0 (1.9) | 9 | 10.5 | 4.0 |
| Возможность | Android | Chrome для Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Базовая поддержка | (Да) | (Да) | (Да) | (Да) | (Да) | (Да) |