Iladarsda Iladarsda - 2 months ago 19
Javascript Question

Underscore.js : findWhere with nested property value

How do I go about the filtering below:

[{
"id": 100,
"title": "Tlt1",
"tax": [{
"name": "Tax1",
"id": 15
}, {
"name": "Tax1",
"id": 17
}]
}, {
"id": 101,
"title": "Tlt2",
"tax": [{
"name": "Tax2",
"id": 16
}]
}, {
"id": 102,
"title": "Tlt3",
"tax": [{
"name": "Tax3",
"id": 17
}, {
"name": "Tax3",
"id": 18
}]
}]


to get only those where
tax.id
is
17
, as per below:

[
{
"id": 100,
"title": "Tlt1",
"tax": [
{
"name": "Tax1",
"id": 15
},
{
"name": "Tax1",
"id": 17
}
]
},
{
"id": 102,
"title": "Tlt3",
"tax": [
{
"name": "Tax3",
"id": 17
},
{
"name": "Tax3",
"id": 18
}
]
}
]


Currently I use the method below, but maybe there is more clean way of going about this?

var arr = [];
_(data).each(function (v1, k1) {
_(v1.tax).each(function (v2, k2) {
if (v2.id == id) {
arr.push(v1);
}
});
});


Demo here: http://jsfiddle.net/7gcCz/2/

Any suggestion much appreciated.

Answer

You may use the combination of _.filter and _.where

_.filter(data, function(obj) {
    return _.where(obj.tax, {id: ID_TO_FIND}).length > 0;
})

See demo: http://jsfiddle.net/hCVxp/

Update


Thanks to @GruffBunny. A more efficient way is to use _.some to avoid looping through all tax items:

var arr = _.filter(data, function(obj) {
    return _.some(obj.tax, {id: ID_TO_FIND});
});

See demo: http://jsbin.com/putefarade/1/edit?html,js,console

Comments