2013-02-27 177 views
20

我想過濾一個基於另一個對象的數組。共同財產編號id。 我不確定過濾器+每個都是執行此操作或映射縮減的最佳方法。無論如何,下面的代碼不起作用,因爲out是空列表。underscore.js過濾一個基於另一個對象的數組

var aaa = [ 
    {name: "AAA", id: 845}, 
    {name: "BBB", id: 839}, 
    {name: "CCC", id: 854} 
]; 
var bbb = [ 
    {id: 839}, 
    {id: 854} 
]; 

var out = _.filter(aaa, function(val){ 
    return _.each(this, function(val2){ 
     return val['id'] === val2['id'] 
    }); 
}, bbb); 

回答

37

只需創建一個有效ID 「設置」 和使用 「設置」 做濾波:

var aaa = [ 
    {name: "AAA", id: 845}, 
    {name: "BBB", id: 839}, 
    {name: "CCC", id: 854} 
]; 
var bbb = [ 
    {id: 839}, 
    {id: 854} 
]; 

var ids = {}; 
_.each(bbb, function (bb) { ids[bb.id] = true; }); 

var out = _.filter(aaa, function (val) { 
    return ids[val.id]; 
}, bbb); 

灌裝ids快,它在N * amortized O(1)即O(n)。過濾同樣適用。

如果在內循環中使用each(…),則會有O(n²)。對於更大的數據集,這將變得非常緩慢。另外,嵌套使代碼更難以第一眼看懂。

見該代碼在行動剪斷:http://jsfiddle.net/SMtX5/

+1

thans爲解釋和推理背後。 – bsr 2013-02-27 20:45:33

2

您可以使用_.some(list, [iterator], [context])

它返回如果任何在列表值的傳遞迭代真相的考驗。

var out = _.filter(aaa, function(val){ 
    return _.some(this,function(val2){ 
     return val2['id'] === val['id']; 
    }); 
}, bbb); 

這裏是jsfiddle。 http://jsfiddle.net/h98ej/

+0

基於接受的答案,這個例程比所接受的要快得多嗎? – 2016-10-17 16:03:27

15

可以使用_.find過濾:

_.filter(aaa, function(a){ 
    return _.find(bbb, function(b){ 
     return b.id === a.id; 
    }); 
}); 
1
bbb = bbb.map(_ => _.id) && aaa.filter(_ => bbb.indexOf(_.id) > -1) 

你只需要純JS數組函數做假設你的使用情況。

相關問題