如何通过属性值从数组中删除对象?

时间:2016-06-19 14:51:59

标签: javascript

我有这个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中实现它的优雅方法是什么?

4 个答案:

答案 0 :(得分:2)

我会在arr2中获得所有ID的精简列表,然后在indexOf中使用findfilter来排除修订版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的改进:

enter image description here

特别是在过滤器上显示出超过20%的改进。 取自this article.