通过ID合并数组的重复数据,并将重复数据的某个属性值加在一起

将数组里有相同ID的数据合并到一起,并将相同ID的数据里的num的值相加。

假设数据为:

let oldArr = [
    { num: 123, id: 'id1' },
    { num: 124, id: 'id2' },
    { num: 125, id: 'id1' },
    { num: 126, id: 'id1' },
    { num: 127, id: 'id3' },
];

期待得到的数据:
期待数据

!!!为了测试几种方法的性能,写了一个makeMoreOldarr函数为oldArr添加更多数据(数据太少,可能无法捕捉):

function makeMoreOldarr () {
    for (let i = 0; i < 10000; i++) {
      oldArr.push({
        num: i,
        id: 'id'+i
     })
   }
}

方法一:两次for循环+indexOf()

代码:

// 两次for循环
    function getnumByDoubleFor (arr) {
      let newArr = []
      temp = []
      for (let i = 0; i < arr.length; i++) {
        if (temp.indexOf(arr[i].id) === -1) {
          newArr.push({
            num: arr[i].num,
            id: arr[i].id
          })
          temp.push(arr[i].id)
        } else {
          for (let a = 0; a < newArr.length; a++) {
            if (newArr[a].id === oldArr[i].id) {
              newArr[a].num += oldArr[i].num
              break;
            }
          }
        }
      }
      return newArr
    }

耗时:227.7ms (超级耗时,几种方法里最耗时的一种)
getnumByDoubleFor方法耗时

方法二:for循环+indexOf()

代码:

//for循环+indexOf
function getnumsByIndexOf (arr) {
    var newArr = []
    var temp = []
    for (let i = 0; i < arr.length; i++) {
      if (temp.indexOf(arr[i].id) == -1) {
        newArr.push({
          num: arr[i].num,
          id: arr[i].id
        })
        temp.push(arr[i].id)
      } else {
        var index = temp.indexOf(arr[i].id)
        newArr[index].num += arr[i].num
      }
    }
    return newArr
}
  getnumsByIndexOf(oldArr);

耗时:211.5ms(也超级耗时,只比两次for循环好一点点)
getnumsByIndexOf方法耗时

方法三、for循环+map

代码:

// for循环+map
    function getnumByMap (arr) {
      let mapArr = new Map()
      let newArr = []
      for (let i = 0; i < arr.length; i++) {
        mapArr.has(arr[i].id) ? mapArr.set(arr[i].id, mapArr.get(arr[i].id) + arr[i].num) : mapArr.set(arr[i].id, arr[i].num)
      }
      mapArr.forEach((item, index) => {
        newArr.push({
          id: index,
          num: item
        })
      })
      return newArr
    }

耗时:7.9ms(比for循环+indexOf好多啦,和filter+ map + for of差不多)
getnumByMap方法耗时

方法四、filter+ map + for of

代码:

//filter+ map + for of
    function getnumByFilter (arr) {
      let maps = new Map()
      let newArr = []
      arr.filter((item) => {
        !maps.has(item.id) ? maps.set(item.id, item.num) : maps.set(item.id, item.num + maps.get(item.id))
      })
      for (let [key, num] of maps) {
        newArr.push({
          id: key,
          num: num
        })
      }
      return newArr;
    }

耗时:7.5ms(和for循环+map差不多)

getnumByFilter方法耗时

方法五、filter+ map + forEach

代码:

//filter+ map + forEach
    function getnumByFilterForEach (arr) {
      let maps = new Map()
      let newArr = []
      arr.filter((item) => {
        !maps.has(item.id) ? maps.set(item.id, item.num) : maps.set(item.id, item.num + maps.get(item.id))
      })
      maps.forEach((item, index) => {
        newArr.push({
          id: index,
          num: item
        })
      })
      return newArr;
    }

耗时:4.7ms(最快的!)
getnumByFilterForEach方法耗时

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值