2015-05-27 61 views
3

現在我有兩個對象數組,如何使用lodash或下劃線刪除兩個數組中的相同對象?

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'}]; 

我想刪除arr1arr2的相同id這些對象,所以結果是:

var arr1 = [{id: 1, name: 'Ben'}, {id: 3, name: 'Gavin'}]; 
var arr2 = [{id: 5, name: 'Jet'}]; 

如何使用lodashunderscore實現它?

這是我的實現。

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); }); 

有沒有什麼更好的方法來做到這一點?

+0

不能用['.uniq'](https://lodash.com/docs#uniq)完成? – Dom

+0

如何用'uniq'做到這一點? – zangw

+0

定義「更好」。這是否更快?較少的代碼?更容易維護? ;-) – RobG

回答

2

你可以使用_.difference嗎?

same_elements = _.intersection(arr1, arr2); 
arr1 = _.difference(arr1, same_elements); 
arr2 = _.difference(arr2, same_elements); 
+1

我不認爲'.intersection()'會正確比較內部對象。 –

+0

@Ja͢ck然後使用'_.intersectionBy()'或'_.intersectionWith()'。 – trusktr

2

我不知道這應該如何用下劃線或lodash來完成,但這裏是一個JavaScript實現。

它創建一個過濾器函數,然後您可以應用於這兩個數組只保留不屬於交叉點的元素。

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);

1

我覺得你的算法是正確的,這裏是純JS稍微不同的方法。我用a, b代替arr1, arr2爲簡潔:

// 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只是用來每個數組向後遍歷,使拼接不影響迭代。

相關問題