bsr
bsr

Reputation: 58662

underscore.js filter an array of objects, based on another

I am trying to filter an array of objects, based on another. The common property id id. I am not sure filter + each is the best way to do it or map reduce. Anyway, below code doesn't work as out is empty list.

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

Upvotes: 23

Views: 32378

Answers (4)

Tony Broyez
Tony Broyez

Reputation: 21

bbb = bbb.map(_ => _.id) && aaa.filter(_ => bbb.indexOf( _.id ) > -1)

You just need pure JS array functions to do that assuming your use case.

Upvotes: 2

Kijewski
Kijewski

Reputation: 26022

Just create a "set" of the valid ids and use that "set" to do the filtering:

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

Filling ids is fast, it's in n * amortized O(1), i.e O(n). Same holds for the filtering.

If you use each(…) in the inner loop, you will have O(n²). For bigger data sets this would become very slow. Also the additional nesting make the code more difficult to read/understand at first glance.

See that code snipped in action: http://jsfiddle.net/SMtX5/

Upvotes: 40

anhulife
anhulife

Reputation: 566

you can use _.find to filter:

_.filter(aaa, function(a){
    return _.find(bbb, function(b){
        return b.id === a.id;
    });
});

Upvotes: 20

pktangyue
pktangyue

Reputation: 8524

You can use _.some(list, [iterator], [context]).

It returns true if any of the values in the list pass the iterator truth test.

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

Here is jsfiddle. http://jsfiddle.net/h98ej/

Upvotes: 2

Related Questions