Search code examples
javascriptarrayslodash

How do I search an array of nested objects for field names?


I'm looking for a couple of different ways to access the data below, using ES6 and/or lodash.

What I'm trying to do is to return the parent object, where device_id matches.

i.e, for each item in entities, if in any of the nested objects, the device_id field = abc, return the whole array item

const entities = [
    {
        "<unknown key>": {
            "entity_id": "something",
            "device_id": "abc"
        },
        "<unknown key>": {
            "entity_id": "else",
            "device_id": "abc"
        },
    },
    {
        "<unknown key>": {
            "entity_id": "hello",
            "device_id": "xyz"
        },
        "<unknown key>": {
            "entity_id": "world",
            "device_id": "xyz"
        }
    }
]

Solution

  • Use Array::find() to find the item with matching a child with the given device_id:

    const res  = entities.find(o => Object.values(o).some(x => x.device_id === 'abc'));
    console.log(res);
    <script>
        const entities=[{"<unknown key>":{entity_id:"something",device_id:"abc"},"<unknown key2>":{entity_id:"else",device_id:"abc"}},{"<unknown key>":{entity_id:"hello",device_id:"xyz"},"<unknown key2>":{entity_id:"world",device_id:"xyz"}}];
    </script>

    If you are interested in speed, use for..in instead of Object.values().some(). That way you avoid an intermediate array:

    ` Chrome/120
    -------------------------------------------------------------------
    for..in               1.00x  |  x100000000  649  671  671  678  683
    Object.values()       1.79x  |   x10000000  116  116  117  122  133
    -------------------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    

    const entities=[{"<unknown key>":{entity_id:"something",device_id:"abc"},"<unknown key2>":{entity_id:"else",device_id:"abc"}},{"<unknown key>":{entity_id:"hello",device_id:"xyz"},"<unknown key2>":{entity_id:"world",device_id:"xyz"}}];
        
    // @benchmark Object.values()    
    
    entities.find(o => Object.values(o).some(x => x.device_id === 'abc'));
    
    // @benchmark for..in
    entities.find(o => {
      for(const key in o){
        if(o[key].device_id === 'abc') return true;
      }
    });
    
    /*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));