Search code examples
lodash

How to get values in an array from nested array of objects based on a given condition?


I'm using lodash and I have the following array of objects:

[{
    "id": 1,
    "values": [
        {
            "sub": "fr",
            "name": "foobar1"
        }, 
        {
            "sub": "en",
            "name": "foobar2"
        }
    ]
}, 
{
    "id": 2,
    "values": [
        {
            "sub": "fr",
            "name": "foobar3"
        },
        {
            "sub": "en",
             "name": "foobar4"
        }
    ]
}]

What i'm trying to get the list of ID and name for a given "SUB". So, with the previous object, if I send the sub fr I want to get:

[{
    "id": 1,
    "name": "foobar1"

}, 
{
    "id": 2,
    "name": "foobar3"
}]

Do you know if I can easily do it with lodash?

I tried to use _.pick but it doesn't working(I'm a bit lost with these mixes between nested objects and arrays) _.map(data, function (o) { _.pick(o, ['id', 'values.name']) });.

I also tried to use _.filter with things like _.filter(data, { values: [{ sub: 'fr' }]}); but it return all the items. What I'm looking for is to return the nested part only.


Solution

  • You can use flatMap() where its callback returns an array of filtered subs using filter() where each filtered item is transformed using map().

    var result =  _.flatMap(data, item => 
      _(item.values)
        .filter({ sub: 'fr' })
        .map(v => ({id: item.id, name: v.name}))
        .value()
    );
    

    var data = [{
        "id": 1,
        "values": [
            {
                "sub": "fr",
                "name": "foobar1"
            }, 
            {
                "sub": "en",
                "name": "foobar2"
            }
        ]
    }, 
    {
        "id": 2,
        "values": [
            {
                "sub": "fr",
                "name": "foobar3"
            },
            {
                "sub": "en",
                 "name": "foobar4"
            }
        ]
    }];
    
    var result =  _.flatMap(data, item => 
      _(item.values)
        .filter({ sub: 'fr' })
        .map(v => ({id: item.id, name: v.name}))
        .value()
    );
               
    document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>