2013-02-27 3 views
20

オブジェクトの配列を別のものに基づいてフィルタリングしようとしています。共通のプロパティID id。 私はフィルター+がそれを行う最善の方法であるか分かりにくいか分からない。とにかく、outは空リストなので、コードの下には機能しません。アンダースコア.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

これは、説明と推論の背後にあるものです。 – bsr

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

受け入れられた答えに基づいて、早くこのルーチンは受け入れられたものと比べて早いですか? –

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の配列関数を必要としています。