How can I delete the same object in two arrays using lodash or underscore?
Now I have two arrays of objects,
var arr1 = [{id: 0, name: 'Jack'}, {id: 1, name: 'Ben'}, {id: 2, name: 'Leon'}, {id: 3, name: 'Gavin'}];
var arr2 = [{id: 0, name: 'Jack'}, {id: 5, name: 'Jet'}, {id: 2, name: 'Leon'}];
I want to delete those objects the same id
in arr1
and arr2
so the results are:
var arr1 = [{id: 1, name: 'Ben'}, {id: 3, name: 'Gavin'}];
var arr2 = [{id: 5, name: 'Jet'}];
How do I implement it with lodash
or underscore
?
Here is my implementation.
arr1_ids = _.pluck(arr1, 'id');
arr2_ids = _.pluck(arr2, 'id');
same_ids = _.intersection(arr1_ids, arr2_ids);
arr1 = _.remove(arr1, function(e) { return !_.contains(same_ids, e.id); });
arr2 = _.remove(arr2, function(e) { return !_.contains(same_ids, e.id); });
Is there a better way to do this?
source to share
I'm not sure how to do this with underscore or lodash, but here's a JavaScript implementation.
It creates a filter function that can then be applied to both arrays to keep only the elements that are not part of the intersection.
var arr1 = [{id: 0, name: 'Jack'}, {id: 1, name: 'Ben'}, {id: 2, name: 'Leon'}, {id: 3, name: 'Gavin'}];
var arr2 = [{id: 0, name: 'Jack'}, {id: 5, name: 'Jet'}, {id: 2, name: 'Leon'}];
var negative_intersection_filter = function(a, b) {
// create a map to speed up the filtering later
var map = a.reduce(function(map, current) {
// perform the intersection
map[current.id] = b.some(function(item) {
return item.id == current.id;
});
return map;
}, {});
// our filtering function, simple
return function(item) {
return !map[item.id];
}
}(arr1, arr2);
// apply the filter here
arr1 = arr1.filter(negative_intersection_filter);
arr2 = arr2.filter(negative_intersection_filter);
console.log(arr1);
console.log(arr2);
source to share
I think your algorithm is right, here's a slightly different approach in simple js. I used a, b
instead arr1, arr2
for brevity:
// Collect ids and sort
var ids = a.map(function(obj) {return obj.id}).concat(b.map(function(obj) {return obj.id})).sort();
// Get IDs that aren't duplicates
var nonDups = ids.filter(function(v, i, o){return v !== o[i-1] && v !== o[i+1]});
// Keep only the non-duplicates in each array
a.reduceRight(function(pre, cur, i, o){if (nonDups.indexOf(cur.id) == -1) o.splice(i, 1)},0);
b.reduceRight(function(pre, cur, i, o){if (nonDups.indexOf(cur.id) == -1) o.splice(i, 1)},0);
JSON.stringify(a) // [{"id":1,"name":"Ben"},{"id":3,"name":"Gavin"}]
JSON.stringify(b) // [{"id":5,"name":"Jet"}]
reduceRight is just used to iterate backward through each array, so splicing doesn't affect the iteration.
source to share