从另一个对象数组中删除对象数组

16

假设我们有以下对象数组,根据属性id进行比较:

a = [{'id':'1', 'name':'a1'}, {'id':'2', 'name':'a2'}, {'id':'3', 'name':'a3'}]

b = [[{'id':'2', 'name':'a2'}, ]

我该如何从a中减去b?使得我们有c = a - b,其结果应为[ {'id':'1', 'name':'a1'}, {'id':'3', 'name':'a3'}]

我尝试使用以下方法:

var c= a.filter(function(item) {
                    return !b.includes(item.id);
                });

但仍未能正常工作。


没有过滤器,你可以在一个简单的循环中完成它,在其中需要检查数组是否具有相同的值:if(a[i].id == b[j].id){ a.splice(i, 1); i-=1; } - Aleksey Solovey
@Jordumus,在我的问题中,我有一些对象,它们应该根据 id 属性进行比较。这不是一个整数或字符串的数组,就像重复的问题那样。 - Codec
@AlekseySolovey 你在提出的解决方案中嵌套了一个循环。 - Codec
@Codec 是一个有效的 JavaScript 代码。 - Aleksey Solovey
4个回答

29

这个解决方案怎么样?它假设'b'也是一个数组,因此对于'a'的每个元素,您都会检查是否在'b'中有匹配的对象。如果有匹配的对象,则在过滤函数中返回false,以便丢弃该元素。

var a = [{
  'id': '1',
  'name': 'a1'
}, {
  'id': '2',
  'name': 'a2'
}, {
  'id': '3',
  'name': 'a3'
}]
var b = [{
  'id': '2',
  'name': 'a2'
}]

var c = a.filter(function(objFromA) {
  return !b.find(function(objFromB) {
    return objFromA.id === objFromB.id
  })
})

console.log(c)


19

这里有一个简洁的答案 :)

基本上,您可以进行过滤,就像您已经尝试过的那样。然后您还可以为每个a元素过滤b,并且如果过滤后的b长度为零,则返回true,因为这意味着a元素是唯一的。

var a = [{
  'id': '1',
  'name': 'a1'
}, {
  'id': '2',
  'name': 'a2'
}, {
  'id': '3',
  'name': 'a3'
}];

var b = [{
  'id': '2',
  'name': 'a2'
}];

c = a.filter( x => !b.filter( y => y.id === x.id).length);
console.log(c);


10

新的ES6语法让它变得更简单

我想第二和第三种方式更有效率....

a.filter(i => !b.filter(y => y.id === i.id).length); // One Way
a.filter(i => !b.find(f => f.id === i.id)); // Second Way
a.filter(i => b.findIndex(f => f.id === i.id)) // Third Way

1
首先,你只需构建要删除的 ID 的映射表。然后,您可以使用该映射表来过滤您的第一个数组,像这样:

var a = [{
  'id': '1',
  'name': 'a1'
}, {
  'id': '2',
  'name': 'a2'
}, {
  'id': '3',
  'name': 'a3'
}];
var b = [{
  'id': '2',
  'name': 'a2'
}];

var idsToDelete = b.map(function(elt) {return elt.id;});
var result = a.filter(function(elt) {return idsToDelete.indexOf(elt.id) === -1;});
console.log(result)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接