js反向排序与删除对象数组中含有特定属性的对象

最近遇到一个需求,需要写一个方法,方法接受一个数组(数组中是一个个的对象)、一个属性名、一个属性的value。之后在这个方法中,将数组中有对应value和属性名的对象给删除

比如对于下面这个对象数组

const testArray =[
{name:'a',id:'999',location:[5,6]},
{name:'b',id:'998',location:[5,6]},
{name:'c',id:'997',location:[3,2]},
{name:'d',id:'998',location:[1,2]}
]

我们定义一个方法objectArrayDelete,当执行objectArrayDelete后

objectArrayDelete(testArray,'id','998')

会返回一个全新数组(id为998的对象都被删除)

const testArray =[
{name:'a',id:'999',location:[5,6]},
{name:'c',id:'997',location:[3,2]}
]

说干就干,我噼里啪啦打了一通

export const objectArrayDelete = (originArray: any[], attribute: string, value: any) => {
  let newArray = originArray
  for (let i = 0; i < newArray.length; i++) {
    if (newArray[i][attribute] && newArray[i][attribute] === value) {
      newArray.splice(i, 1)
    }
  }
  return newArray
}

打完之后就觉得不对,这一段初看没什么问题,循环遍历newArray,当属性存在且属性的值等于我们传进来的参数value后,执行splice

因为用到了splice,这样的话会有两个问题

(1)第二行的let newArray = originArray,只会创建一个数组的引用,那么在后面执行splice的时候,看似给newArray执行的,实际上是直接给我们的原本数组执行的,这样就会非常危险而且不符合数据规范,我们希望返回的是一个新数组

(2)函数的循环逻辑不太对,当我们执行splice后,数组的长度、下标等等都已经改变,如果还按照原来的循环,先不说循环次数i会不会超出数组大小的问题,当我们的数组有多个应该被删除对象时,肯定会出现无法删除完全的事情

第一个解决思路是我们定义一个数组,这个数组保存我们需要删除的对象下标,之后我们再跑一次循环

那么这样又有一个问题就是splice必定会改变数组的下标排序,那么我们保存的下标实际上是没有意义的,这样还是会有问题

查了一下,发现可以用反向排序

export const objectArrayDelete = (originArray: any[], attribute: string, value: any) => {
  let newArray = [...originArray]
  for (let i = newArray.length - 1; i >= 0; i--) {
    if (newArray[i][attribute] && newArray[i][attribute] === value) {
      newArray.splice(i, 1)
    }
  }
  return newArray
}

主要核心是 for (let i = newArray.length - 1; i >= 0; i--)

这里是和以往的数组遍历不同,是从数组末尾向前遍历的,当我们执行splice后,我们不用关心i下标变化的问题,因为在splice后数组前面的下标是不会变的

最后,我们再处理一下,当value是数组的时候,无法直接用===判断的问题,一个删除对象数组中含有特定属性的对象的方法就写好了

//对象数组删除某个有属性值的某一对象
export const objectArrayDelete = (originArray: any[], attribute: string, value: any) => {
  let newArray = [...originArray]
  if (Array.isArray(value)) {
    for (let i = newArray.length - 1; i >= 0; i--) {
      if (newArray[i][attribute] && newArray[i][attribute].toString() === value.toString()) {
        newArray.splice(i, 1)
      }
    }
  } else {
    for (let i = newArray.length - 1; i >= 0; i--) {
      if (newArray[i][attribute] && newArray[i][attribute] === value) {
        newArray.splice(i, 1)
      }
    }
  }
  return newArray
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值