web-dev-qa-db-ja.com

underscore.jsは、別のオブジェクトに基づいてオブジェクトの配列をフィルタリングします

別のオブジェクトに基づいて、オブジェクトの配列をフィルタリングしようとしています。共通プロパティID id。フィルター+それぞれが最適な方法であるか、マップを縮小するかはわかりません。とにかく、以下のコードはoutが空のリストであるため機能しません。

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

有効な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/

38
kay

_.findを使用してフィルタリングできます:

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

ユースケースを想定して、純粋なJS配列関数が必要です。

2
Tony Broyez

_.some(list, [iterator], [context]) を使用できます。

listのいずれかの値がiterator真理値テストに合格した場合、 true を返します。

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

これがjsfiddleです。 http://jsfiddle.net/h98ej/

2
pktangyue