reduce() 方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。
arr.reduce(callback[, initialValue])
参数
callback
执行数组中每个值的函数,包含四个参数:
accumulator
累加器累加回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(如下所示)。
currentValue
数组中正在处理的元素。
currentIndex
数组中正在处理的当前元素的索引。 如果提供了initialValue,则索引号为0,否则为索引为1。
array
调用reduce的数组
initialValue
[可选] 用作第一个调用 callback的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
返回值
函数累计处理的结果
reduce运行原理
假如运行下段代码:
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
return accumulator + currentValue;
});
如果你打算提供一个初始值作为reduce方法的第二个参数,以下是运行过程及结果:
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { return accumulator + currentValue; }, 10 );
运用实例
数组里所有值的和
var sum = [0, 1, 2, 3].reduce(function (a, b) {
return a + b;
}, 0);
// sum is 6
你也可以写成箭头函数的形式:
var total = [ 0, 1, 2, 3 ].reduce(
( acc, cur ) => acc + cur,
0
);
将二维数组转化为一维
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
function(a, b) {
return a.concat(b);
},
[]
);
// flattened is [0, 1, 2, 3, 4, 5]
你也可以写成箭头函数的形式:
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
( acc, cur ) => acc.concat(cur),
[]
);
计算数组中每个元素出现的次数
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
var countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
}
else {
allNames[name] = 1;
}
return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
使用扩展运算符和initialValue绑定包含在对象数组中的数组
// friends - an array of objects
// where object field "books" - list of favorite 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 - list which will contain all friends' books +
// additional list contained in 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'
// ]