reduce用法

208 阅读2分钟

概念

reduce方法能搞定的东西,循环大多都能搞定;循环我们已经很了解了,看一下reduce吧! reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。本质上也是一个循环,不过在循环中保存了上次循环的状态。

语法及参数

array.reduce(callBack(total, currentValue, currentIndex, arr), initialValue)
  • total 必需。上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值则为初始值initialValue,否则为数组第一项array[0];
  • currentValue 必需。当前元素。 在第一次调用,若指定了初始值initialValue,则值为array[0],否则从array[1]开始。
  • currentIndex 可选。当前元素的索引。
  • arr 可选。用于遍历的数组。
  • initialValue 可选。传递给函数的初始值。

需要注意的事,对于空数组,不传初始值会报错。所以给定一个初始值总是保险的。

捕获.PNG

举例:数组求和

let sum = [1, 2, 3, 4].reduce((preVal, curVal) =>{
  return preVal + curVal
}, 0) //10

常用案例

1.数组去重

let arr = ['a', 'b', 'c', 'd', 'e', 'e', 'd', 'c', 'd', 'b', 'a', 'd']
let arr2 = arr.reduce((preVal, curVal) => {
  if (preVal.includes(curVal)) {
    preVal.push(curVal)
  }
  return preVal
}, [])

2.数组扁平化

let arr = [0,[1], [2, 3], [4,[5,6]]]
const newArr = (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]

3.计算元素出现次数

let arr = ['a', 'b', 'c', 'd', 'e', 'e', 'd', 'c', 'd', 'b', 'a', 'd']

let countsObj = arr.reduce((obj, o) =>{
  if (o in obj) {
    obj[o]++
  }
  else {
    obj[o] = 1
  }
  return obj
}, {})

4.对象里的属性求和

var arr = [
    {
        //...
        score: 80
    },
    {
        //...
        score: 90
    },
    {
        //...
        score: 90
    }
];

var sum = arr.reduce((prev, cur) =>{
    return cur.score + prev;
}, 0);
console.log(sum) //270

原理

function myReduce(callback, initVal) {
	let arr = this
	if(!(arr instanceof Array)) {
		throw (`${callback}.myReduce is not function`)
	}
	if(typeof callback != 'function') {
		throw(`${callback} is not function`)
	}
	if(!arr.length) return;

	let prev = initVal || arr[0];
	let idx = initVal ? 0 : 1;
	for(; idx<arr.length; idx++) {
		prev = callback(prev, arr[idx], idx, arr)
	}
	return prev
}

使用myReduce代替reduce

捕获.PNG