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)

 

posted @ 2019-05-24 12:19  潇湘羽西  阅读(17679)  评论(1编辑  收藏  举报