我有这个javascript对象:
var arr1 = [{id:'124',name:'qqq'},
{id:'589',name:'www'},
{id:'45',name:'eee'},
{id:'567',name:'rrr'}]
var arr2 = [{id:'124',name:'ttt'},
{id:'45',name:'yyy'}
从arr1我需要删除arr2中具有相同id的所有对象。
这是arr1的理想结果:
var arr1 = [{id:'589',name:'www'},
{id:'567',name:'rrr'}]
在Javascript中实现它的优雅方法是什么?
答案 0 :(得分:2)
我会在arr2
中获得所有ID的精简列表,然后在indexOf
中使用find
或filter
来排除修订版arr1
中的ID }:
var arr1 = [{
id: '124',
name: 'qqq'
}, {
id: '589',
name: 'www'
}, {
id: '45',
name: 'eee'
}, {
id: '567',
name: 'rrr'
}];
var arr2 = [{
id: '124',
name: 'ttt'
}, {
id: '45',
name: 'yyy'
}];
var ids = arr2.map(function(it) {
return it.id;
});
var unique = arr1.filter(function(it) {
return ids.indexOf(it.id) === -1; // does not contain
});
console.log(unique);

如果您不想映射ID - 虽然我建议这样做,因为这意味着您不必反复遍历arr2
- 您可以使用某些内容像:
var unique = arr1.filter(function(it) {
return !arr2.some(function (other) {
return it.id === other.id;
});
});
答案 1 :(得分:2)
这是一种即时获取ID值的方法。它通过this
的{{3}}将中间对象绑定到filter
:
var arr1 = [{id:'124',name:'qqq'},
{id:'589',name:'www'},
{id:'45',name:'eee'},
{id:'567',name:'rrr'}];
var arr2 = [{id:'124',name:'ttt'},
{id:'45',name:'yyy'}];
arr1 = arr1.filter(function (el) {
return !this[el.id];
}, arr2.reduce(function (obj, el) {
return obj[el.id] = 1, obj;
}, {}));
console.log(arr1);
作为filter
的最后一个参数传递的中间对象如下所示:
{ 45: 1, 124: 1 }
这样可以直接检查arr1
的元素是否需要被拒绝。
答案 2 :(得分:1)
我建议使用哈希表。
var arr1 = [{ id: '124', name: 'qqq' }, { id: '589', name: 'www' }, { id: '45', name: 'eee' }, { id: '567', name: 'rrr' }],
arr2 = [{ id: '124', name: 'ttt' }, { id: '45', name: 'yyy' }];
arr1 = arr1.filter(function (a) {
return !this[a.id];
}, function (hash) {
arr2.forEach(function (a) { hash[a.id] = true; });
return hash;
}(Object.create(null)));
console.log(arr1);

ES6
var arr1 = [{ id: '124', name: 'qqq' }, { id: '589', name: 'www' }, { id: '45', name: 'eee' }, { id: '567', name: 'rrr' }],
arr2 = [{ id: '124', name: 'ttt' }, { id: '45', name: 'yyy' }];
arr1 = arr1.filter((hash =>
(arr2.forEach(a => hash[a.id] = true), a => !hash[a.id]))(Object.create(null)));
console.log(arr1);

答案 3 :(得分:-2)
我非常鼓励使用underscorejs进行这种对象操作。来自the documentation:
var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]
如果你想在一个对象上做同样的事情:
_.filter({"a":1,"b":2,"c":3,"d":4}, function(value,key){ return value % 2 == 0; })
在您的具体情况下,这将是解决方案:
var newArray = _.filter(arr1,(object1) => {
return !_.contains(_.pluck(arr2,'id'),object1.id);
});
这是一张图表,显示了本地方法上Underscore和Lodash的改进:
特别是在过滤器上显示出超过20%的改进。 取自this article.