首先先了解下数组高阶函数之--------reduce
基本语法:
它是如何工作的?
reducer 函数逐个遍历数组元素。在每一步中,reducer 函数将当前数组值添加到上一步的结果中,直到没有更多元素要添加。
参数是什么?
参数是回调函数和可选的初始值。
回调函数
preVal:它是前一个回调函数产生的前一个值。
currVal:它是数组的当前元素,reducer 函数会传播它。
currentIndex:当前索引。但是,它是可选的。
arrayToTraverse:要遍历的数组。它也是可选的。
初始值
初始值参数是可选的。它是第一次调用回调时,将前一个值初始化的值。如果未指定初始值,则将前一个值初始化为初始值,将当前值初始化为数组中的第二个值。
案例1:数组求和
var arr=[5.99,2.99,3.99,11.99]; arr.reduce(function(pre,item,index,arr){ return pre+item }) //24.96
//传入初始值
var arr=[5.99,2.99,3.99,11.99]; arr.reduce(function(pre,item,index,arr){ return pre+item },10) //34.96
//函数简化写法:
const sum = arr.reduce((preVal, currVal) => preVal + currVal, 0);
微信提示:你可能更喜欢使用 for 循环或 for-each 循环来对上述数组的元素求和,但是,如果使用 reduce(),则可以编写更少的代码。
案例2:展平数组(二维数组转换为一维数组。)
var rows = [[2, 3, 5], [1, 2, 4], [8, 5, 5]] var matrixElements = rows.reduce( function (prev, current) { return prev.concat(current); });
[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]
flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。
案例3:从数组中获取对象
例如,你有一个字符串数组,它们是彩色苹果。使用 reduce() 你可以构造一个苹果对象,如下所示。
const apples = ['green', 'red', 'red', 'yellow', 'red', 'yellow', 'green', 'green']; var appleMap = apples.reduce((prev, apple) => { if (prev[apple] >= 1) prev[apple]++; else prev[apple] = 1; return prev; }, {}); console.log(appleMap); // result: {green: 3, red: 3, yellow: 2}
案例4:对象数组去重问题
function arrDistinctByProp(arr,prop){ let obj = {}; return arr.reduce(function(preValue,item){ obj[item[prop]] ? '' : obj[item[prop]] = true && preValue.push(item); return preValue },[]) }