reduce为数组中的每一个元素依次执行
callback`函数,不包括数组中被删除或从未被赋值的元素,callback接受四个参数:
accumulator 累加器
currentValue 当前值
currentIndex 当前索引
array 数组
arr.reduce(callback[, initialValue])
initialValue
可选
作为第一次调用 callback函数时
的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
var result=[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { return accumulator + currentValue; }, 10 );
运行机制:
第一步: 先判断reduce ()方法里面有没有第二个参数 我们这里发现,有第二个参数,为10
第二步: 把10 作为 callback函数里的第一个参数 在这里 accumulator 为10 currentValue 为数组中的第一值 0 currentIndex 这里从0 开始 执行完一次callback 函数 得到 10+0 =10
第三步 当第二次执行callback 函数的时候, accumulator 为上次运行的结果 10 currentValue为数组中的第二个值 1 currentIndex 为1 执行完第二次callback 的结果为 为 10+1 =11
第四步 第三次执行 callback函数的时候, accumulator 为上次运行的结果 11 currentValue 为数组中的第三个值 2 currentIndex 为2 执行完第三次callback 的结果 为 11+2 =13
第五步 第四次执行 callback函数的时候, accumulator 为上次运行的结果 13 currentValue 为数组中的第四个值 3 currentIndex 为3 执行完第四次callback 的结果 为 13+3 =16
第六步 第五次执行 callback函数的时候, accumulator 为上次运行的结果 16 currentValue 为数组中的第五个值 4 currentIndex 为4 执行完第四次callback 的结果 为 16+4 =20
第七步 : 最后把结果返回为 result
回调函数第一次执行时,accumulator
和currentValue
的取值有两种情况:如果调用reduce()
时提供了initialValue
,accumulator
取值为initialValue
,currentValue
取数组中的第一个值;如果没有提供 initialValue
,那么accumulator
取数组中的第一个值,currentValue
取数组中的第二个值。
由reduce
返回的值将是上次回调调用的值(10)。
第二种情况
如果你打算提供一个初始值作为reduce
方法的第二个参数,以下是运行过程及结果:
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { return accumulator + currentValue; }, 10 ); //20
例子Section
数组里所有值的和
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
);
将二维数组转化为一维Section
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),
[]
);
计算数组中每个元素出现的次数Section
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绑定包含在对象数组中的数组Section
// 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']);
运行机制:1 这里有传参数,把 ['Alphabet'] 当做prev , 然后通过三个点...解析成 'Alphabet'
2 curr 是friends数组中的每一个对象 , curr.books 则代表每个对象的每个数组 在这里表现为 3个数组 ['Bible', 'Harry Potter'], ['War and peace', 'Romeo and Juliet'], ['The Lord of the Rings', 'The Shining'],
3 通过3个点 解析出数组中每个值 结果为 'Alphabet' 'Bible', 'Harry Potter' 然后返回出一个新数组 ['Alphabet' 'Bible', 'Harry Potter']
4 然后 不断的执行 这个callback 函数
// allbooks = [
// 'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
// 'Romeo and Juliet', 'The Lord of the Rings',
// 'The Shining'
// ]
数组去重Section
let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
var res=arr.sort() //返回一个排序后的数组
console.log(res) //[1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 5]
let result = arr.sort().reduce((init, current)=>{
if(init.length===0 || init[init.length-1]!==current){
init.push(current);
}
return init;
}, []);
解析步骤 1 先执行 var res=arr.sort() //返回一个排序后的数组 //[1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 5]
2 这里传了一个空数组 [] 所以 init 此时是 [ ] current 是数组的第一个值 为 1
3 第一次执行 reduce的回调函数的时候 init.length===0 ,所以进来if 判断 此时 执行
init.push(current); 把 1 追加到 init 现在 init 为 [1]
4 第二次执行 回调函数的时候 curreunt 1 此时 if判断此时进不来 所以不执行 直接跳出
5 然后每一次执行回调函数 ,每一次进行判断 所以 达到数组去重
console.log(result); //[1,2,3,4,5]