巧妙改造数组---splice的妙用

524 阅读2分钟

问题背景

有一天产品经理找到我,让我把显示的图表补全。
这个图表是根据搜索框的选择日期显示每个时间段的缴费订单个数,如果日期选择器只选了一天,需要显示这天24小时内详细的缴费订单数据。目前后端的返回数据只有必要的数据,即那个时间点有数据的话,只返回那个时间点,其他时间点并没有返回。渲染到图表上的时候是这样的: 微信截图_20211209131451.png 想要实现的效果是这样的,即便没有数据,也要把所有的数据点显示出来,类似这样 微信截图_20211209131513.png

解决过程

我想着这也没多难呀,后端返回的时候加上不就好了。但后端同事*********,想起来沟通又是麻烦事儿,不如自己补全好了,正好练练我的ES6大法。

两个数组进行比对

首先拿到后台返回的数据,类似:

let {data:arr}= await getPaymentOrder(this.queryBean)
// arr = [
// {dateNo:"10",totalAmount:300,totalCount:20},
// {dateNo:"12",totalAmount:100,totalCount:5}
// ]

我最开始想到的就是新建一个24小时的数组,然后对两个数组都进行遍历,如果少哪个时间点的数据,就插进去,但是要进行双层for循环,但是实现起来比较麻烦。
有没有更好的实现方法呢?
我发现dateNo在数组的对象里面,用起来比较麻烦,于是首先用一个map函数将dateNo映射出来成为一个独立的数组。然后我想到要补全的时间点是固定的,就是说———不管用什么方法,最终得到的都是一个24小时的数组。
那我能不能这样做呢?
也就是使用了一个循环24次的for循环,对每个时间点的数据进行查询,如果缺失的话把数据push到数组里

// 如果是某天的数据的话,对数据进行改造补全
if(this.queryBean.chargeTimeBegin === this.queryBean.chargeTimeEnd){
  let arrDateNoList = arr.map(item=>{
    return item.dateNo
  })
  for (let i =0;i<24;i++){
    let j = i<10?`0${i}`:`${i}`
    if(arrDateNoList.indexOf(j) === -1){
      let tempObj = {
        dateNo:j,
        totalAmount:0,
        totalCount:0
      }
      arr.push(tempObj)
    }
  }
}

最终将数据显示出来的是这样的

微信截图_20211209131400.png 很快我就发现了问题,push是将补全的数据一个一个添加到数组的最后面,那么原有的数据就铁定是在前面显示了。不按照顺序显示的话,那还不如不显示呢。
我突然想到了splice,这个函数可以在特定位置插入数据,何不试试呢?
换成了splice之后和前面的if相结合,最终完美的实现了想要的效果,即在想要的位置插入数据,而且也实现了完美排序。

let arrDateNoList = arr.map(item=>{
  return item.dateNo
})
for (let i =0;i<24;i++){
  let j = i<10?`0${i}`:`${i}`
  if(arrDateNoList.indexOf(j) === -1){
    let tempObj = {
      dateNo:j,
      totalAmount:0,
      totalCount:0
    }
    arr.splice(i,0,tempObj)
  }
}

微信截图_20211209131424.png

总结

虽说是个小功能,但经过了思考,感觉自己是用了最少的代码实现了这个功能,感觉还是不错!。(^o^)/