语法
arr.reduce(callback,[initialValue])
reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
callback (执行数组中每个值的函数,包含四个参数)
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
initialValue (作为第一次调用 callback 的第一个参数。)
默认initialValue
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
})
console.log(sum);
1 2 1
3 3 2
6 4 3
10
带初始值的initialValue
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
},0) // 这里设置了初始值
console.log(sum);
0 1 0
1 2 1
3 3 2
6 4 3
10
结论: 没有提供initialValue,reduce的index 会从索引1的地方开始执行 prev为第0个元素,cur和index从第1个元素开始。如果提供initialValue,从索引0开始,cur和index从第1个元素开始。
导致,如果是个空数组,没有初始值会报错,所以一般都要加个初始值0,确保不会报错。
reduce的用法
- 无脑求和、求积、求差、求除
var arr = [1, 2, 3, 4]; var sum = arr.reduce((x,y)=>x+y) var quadrature = arr.reduce((x,y)=>x*y) var difference = arr.reduce((x,y)=>x-y) var division = arr.reduce((x,y)=>x/y) - 对象里的属性求和
var result = [ { subject: 'math', score: 20 }, { subject: 'chinese', score: 30 }, { subject: 'english', score: 40 } ]; var sum = result.reduce(function(prev, cur) { return cur.score + prev; }, 0); console.log(sum) //90 - 数组去重
let arr = [1,2,3,4,4,1] let newArr = arr.reduce((pre,cur)=>{ if(!pre.includes(cur)){ return pre.concat(cur) }else{ return pre } },[]) console.log(newArr);// [1, 2, 3, 4] - 计算数组中每个元素出现的次数
let names = ['zhang', 'zhao', 'wang', 'wu', 'zhang']; let Num = names.reduce((pre,cur)=>{ if(cur in pre){ pre[cur]++ }else{ pre[cur] = 1 } return pre },{}) console.log(Num); //{zhang: 2, zhao: 1, wang: 1, wu: 1} - 多维数组转化为一维数组
let arr = [[0, 1], [2, 3], [4,[5,6,7]]] const newArr = function(arr){ return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[]) } console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]