Array.reduce()方法
Array.reduce()方法是对数组的遍历,返回一个单个返回值
使用方法:
Array.reduce((acc, cur, idx, src) => {
}, initialValue)
callback回调函数接收4个参数:
Accumulator (acc) (累计器) 如果传入了initialValue,Accumulator的初始值就是initialValue,没传入就是数组的第一个值
Current Value (cur) (当前值)
Current Index (idx) (当前索引)如果传入了initialValue,索引从0开始,没传入从1开始
Source Array (src) (源数组)
initialValue 指定的初始值,初始值可以是数字,数组,对象
Array.reduce()方法之前也没怎么用过,是一次找数组去重方法看到的,看了一下文档,发现它的功能很多,很实用,所以就整理了.下面看具体使用
计算数组之和
// 简单数组各项求和 const arr = [0, 1, 2, 3, 4] const sum = arr.reduce(function(accumulator, currentValue, currentIndex, array){ console.log(accumulator, currentValue, currentIndex, array) return accumulator + currentValue }, 0) // 执行顺序 // 0 0 0 (5) [0, 1, 2, 3, 4] // 0 1 1 (5) [0, 1, 2, 3, 4] // 1 2 2 (5) [0, 1, 2, 3, 4] // 3 3 3 (5) [0, 1, 2, 3, 4] // 6 4 4 (5) [0, 1, 2, 3, 4] console.log(sum) // 10 // accumulator会把上一次循环返回的结果存起来,带到下一次循环中,使用reduce方法可以很容易的计算数组累加,累乘 // 对象数组求和 const arr = [{ count: 10, weight: 1, height: 2 }, { count: 20, weight: 2, height: 4 }, { count: 30, weight: 3, height: 6 }, { count: 40, weight: 4, height: 8 }] // 合计count const obj = arr.reduce((acc, cur) => { return acc + cur.count }, 0) console.log(obj) // 100 // 合计count,weight,height const obj2 = arr.reduce((acc, cur) => { for (let key in cur) { if (!acc[key]) { acc[key] = 0 } acc[key] += cur[key] } return acc }, {}) console.log(obj2) // {count: 100, weight: 10, height: 20}
统计数组元素出现次数
// 普通数组统计 let arr = ['李明', '韩梅梅', '张三', '李明', '李明', '张三', '韩梅梅', '李明', 'Jack', '韩梅梅'] const sum = arr.reduce((acc, cur) => { if (!acc[cur]) { acc[cur] = 0 } acc[cur]++ return acc }, {}) console.log(sum) // {李明: 4, 韩梅梅: 3, 张三: 2, Jack: 1} // 对象数组统计 let arr1 = [{ hobby: 'basketball' }, { hobby: 'badminton' }, { hobby: 'basketball' }, { hobby: 'swim' }, { hobby: 'basketball' }, { hobby: 'swim' }, { hobby: 'pingpong' }] const sum2 = arr1.reduce((acc, cur) => { if (!acc[cur.hobby]) { acc[cur.hobby] = 0 } acc[cur.hobby]++ return acc }, {}) console.log(sum2) // {basketball: 3, badminton: 1, swim: 2, pingpong: 1}
拓展: 统计数组中出现次数最多的元素
// 上面已经获取了每个元素的次数,现在要拿到最大次数的key值 let arr = ['李明', '韩梅梅', '张三', '李明', '李明', '张三', '韩梅梅', '李明', 'Jack', '韩梅梅'] const sum = arr.reduce((acc, cur) => { if (!acc[cur]) { acc[cur] = 0 } acc[cur]++ return acc }, {}) console.log(sum) // {李明: 4, 韩梅梅: 3, 张三: 2, Jack: 1} let max = { count: 0, key: '' } for (let key in sum) { if (max.count < sum[key]) { max.count = sum[key] max.key = key } } console.log(max) // {count: 4, key: "李明"}
二维数组转化为一维数组
let arr = [[1, 2], 3, 4, [5, 6, 7], 8, [9]] let newArr = arr.reduce((acc, cur) => { return acc.concat(cur) }, []) console.log(newArr) // (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
数组去重(很实用,推荐)
// 普通数组去重 let arr = [1, 3, 3, 2, 4, 4, 5, 3, 2, 5, 6] let newArr = arr.reduce((acc, cur) => { if (!acc.includes(cur)) { acc.push(cur) } return acc }, []) console.log(newArr) // (6) [1, 3, 2, 4, 5, 6] // 对象数组去重, 对象数组去重需指定以哪个对象属性来去重 let arr1 = [{ name: '李明', age: 18 }, { name: '韩梅梅', age: 18 }, { name: '韩梅梅', age: 20 }, { name: '李明', age: 20 }, { name: 'jack', age: 22 }, { name: '张三', age: 22 }] function doRepeat (arr, key) { let obj = {} let newArr1 = arr.reduce((acc, cur) => { if (!obj[cur[key]]) { obj[cur[key]] = cur[key] acc.push(cur) } return acc }, []) return newArr1 } // 姓名去重 console.log(doRepeat(arr1, 'name')) // 0: {name: "李明", age: 18} // 1: {name: "韩梅梅", age: 18} // 2: {name: "jack", age: 22} // 3: {name: "张三", age: 22} // age去重 console.log(doRepeat(arr1, 'age')) // 0: {name: "李明", age: 18} // 1: {name: "韩梅梅", age: 20} // 2: {name: "jack", age: 22}
实现笛卡尔积(商品sku计算)
// 测试的数据 let arrs = [['红','黄', '蓝'], ['大', '中', '小'], ['软', '硬']] /** * 思路: 以第一项为基础,循环合并之后的每一项再循环的值 * @param {*} acc 累计的值 * @param {*} cur 当前遍历项 * @param {*} index 当前遍历索引 */ let result = arrs.reduce((acc, cur, index) => { // 从第二项开始合并值 if (index > 0) { let saveArr = [] acc.forEach(item => { cur.forEach(subItem => { saveArr.push(`${item},${subItem}`) }) }) acc = saveArr } return acc }, arrs[0]) // 把数组的第一项传入作为初始值 console.log(result) // ["红,大,软", "红,大,硬", "红,中,软", "红,中,硬", "红,小,软", "红,小,硬", "黄,大,软", "黄,大,硬", "黄,中,软", "黄,中,硬", "黄,小,软", "黄,小,硬",
"蓝,大,软", "蓝,大,硬", "蓝,中,软", "蓝,中,硬", "蓝,小,软", "蓝,小,硬"]0: "红,大,软"1: "红,大,硬"2: "红,中,软"3: "红,中,硬"4: "红,小,软"5: "红,小,硬"6:
"黄,大,软"7: "黄,大,硬"8: "黄,中,软"9: "黄,中,硬"10: "黄,小,软"11: "黄,小,硬"12: "蓝,大,软"13: "蓝,大,硬"14: "蓝,中,软"15: "蓝,中,硬"16: "蓝,小,软"17: "蓝,小,硬", length: 18__proto__: Array(0)