26

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.

Iladarsda
  • 10,640
  • 39
  • 106
  • 170

3 Answers3

51

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

Kiril
  • 2,935
  • 1
  • 33
  • 41
20

Use _.filter to find candidate items and _.some to check for the existence of an item in a collection:

var filteredList = _.filter(list, function(item){
    return _.some(item.tax, { id: 17 });
});
Gruff Bunny
  • 27,738
  • 10
  • 72
  • 59
3

You can do this with _.where alone.

var filteredList  = _.where(list, { tax:[{id:17}] });

Edit: This method works in older version of lodash, but wont work in current underscore or lodash. Working example anyway: https://jsfiddle.net/rhp4crma/

Gray
  • 247
  • 2
  • 5
  • Can someone tell me why this is being downvoted? I tested it and it returns the exact result OP asked for with only 1 command. – Gray Sep 25 '15 at 14:58
  • I tried this and it does not work. Mine returns undefined although the item is present – tno2007 Oct 12 '15 at 15:47
  • 1
    correct syntax is : var filteredList = _.where(list, { tax:{id:17} }); – Sam Jan 27 '16 at 14:44
  • I have up-voted your answer to encourage you to participate in SO, please update your answer with a link to jsfiddle example for this specified case and update your answer corrector as @Sam suggested. – Mahdi Alkhatib Aug 30 '16 at 08:23