【问题标题】:Remove exact object from array从数组中删除确切的对象
【发布时间】:2019-12-12 22:48:45
【问题描述】:

使用以下数组:

randomArray = [
  {alias: 'book1', page: 127}, 
  {alias: 'book1', page: 115}, 
  {alias: 'book2', page: 115}
]

如果我想向数组中添加一个对象(当顺序无关紧要时),我假设我可以简单地:

randomArray.push({alias: 'book3', page: 303})

但是如果我想删除一个对象,比如说我想删除: {alias: 'book1', page: 115},我该怎么做?

我看到过其他堆栈溢出问题,like this,试图找到对象的索引,但他们会假设属性在整个数组中具有唯一值来寻找一个属性。

我的想法:

我想尝试indexOf 然后splice 那个对象,但它不起作用。

randomArray.indexOf({alias: 'book1', page: 115}) 返回-1

查看对象数组并删除完全匹配的有效方法是什么?为了清楚起见,不使用库,所有这些对象都将具有相同的 alias 和 @987654330 @ 属性,不多也不少。 (另外,我应该调用这些属性或键,还是它们是同义词?)

编辑:我已将id 更改为page 以更有意义

【问题讨论】:

  • 你可以使用图书馆吗?
  • @LéoMartin 否定。编辑问题以反映这一点
  • 很遗憾你的 id 不是唯一的 (?)
  • 使用同一问题答案中的代码,只需修改它以查看多个属性...
  • @JamesB 查看我的解决方案

标签: javascript arrays object


【解决方案1】:

肮脏的解决方案(假设对象不包含函数):

const objectToRemove = JSON.stringify({ alias: 'pepper', id: 1 });
const filteredArray = randomArray.filter(item =>
  JSON.stringify(item) !== objectToRemove);

另一种解决方案是从对象构建唯一 ID:

const toRemove = Object.entries({ alias: 'pepper', id: 1 }).join('-');
const filteredArray = randomArray.filter(item =>
  Object.entries(item).join('-') !== toRemove);

或者

const toRemove = 'pepper-1;
const filteredArray = randomArray.filter(item =>
  `${item.alias}-${item.page}` !== toRemove);

【讨论】:

  • 对我来说足够干净!如果您想编辑您的回复以对未来的访问者有意义,我已经编辑了原始问题。我的编辑是将alias 更改为books,将id 更改为page。到时会标记正确
  • 将以同样的方式工作,只需相应地更新 objectToRemove :)
【解决方案2】:

JSON.stringify 和 join 都是非常肮脏的解决方案,并且都依赖于相同顺序的属性,使用深度对象比较函数,然后您可以只使用过滤器返回不包含该项目的数组你想删除。

const compare = (obj1, obj2) =>
  Array.isArray(obj1)
    ? Array.isArray(obj2) && obj1.length === obj2.length && obj1.every((item, index) => compare(item, obj2[index]))
    : obj1 instanceof Date
    ? obj2 instanceof Date && obj1.getDate() === obj2.getDate()
    : obj1 && typeof obj1 === 'object'
    ? obj2 && typeof obj2 === 'object' &&
      Object.getOwnPropertyNames(obj1).length === Object.getOwnPropertyNames(obj2).length &&
      Object.getOwnPropertyNames(obj1).every(prop => compare(obj1[prop], obj2[prop]))
    : obj1 === obj2;
    
const randomArray = [
  {alias: 'book1', page: 127}, 
  {alias: 'book1', page: 115}, 
  {alias: 'book2', page: 115}
];

console.log(randomArray.filter(item => !compare(item, {alias: 'book1', page: 127})));

【讨论】:

  • 您能否提供有关“肮脏解决方案”含义的上下文?对于这个问题,属性将始终处于相同的顺序。我问这个问题是因为这个问题是在第一个答案被标记为正确之后发布的,并且有人投了反对票。
  • 当您可以简单地从给定对象构建唯一复合索引时,这是多么复杂的解决方案
  • 当您的项目中已经有了深度比较功能时,这是一个简单的解决方案。如果您知道它只是别名和页面属性,那么它是矫枉过正的,但此解决方案适用于任何数组。
  • @LéoMartin 我已经使用了您的解决方案。我不明白为什么人们对一个非常适合我给定任务的解决方案(你的)投反对票。
  • 脏意味着将对象变成字符串来比较它们是非常低效的。如果只有两个属性,最有效的解决方案是 randomArray.filter(item => item.alias !== remove.alias && item.page !== remove.page)
猜你喜欢
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 2020-08-14
  • 2015-08-29
  • 2021-12-28
  • 2016-11-26
相关资源
最近更新 更多