简体   繁体   中英

search array of objects by value and return matched object

I have an Array of objects:

[{
  "12": {"data": [{"thisID": "44"},{"thisID": "55"}],
       "settings": {"other":"other"}}
},{
  "15": {"data": [{"thisID": "66"},{"thisID": "77"}],
        "settings": {"other":"other"}}
}]

using underscore.js I would like to access Object which thisID key is 77 .

I did it this way but I believe there is a better way?

var found = _.map(array, function (d) {
        return  _.findWhere(d.data, {thisID: "77"});
    })
    .filter(function(n){ return n != undefined })

console.log(found) //[{thisID:x, a:a, ....}]

First of all, I think that if you are going to use underscore, you should use it for everything -- you should not change back to Javascript's built-in .filter . I believe underscore will defer to the built-in method if it exists otherwise it will substitute it's own implementation

Second of all because of the nested nature of your data, you need to filter your objects based on further filtering their value's data attribute. This accounts for _.values(obj)[0].data being passed as the first argument to the second call to filter.

Finally, if you are sure there will only ever be one object with the desired thisID value, you can always reference found[0] in the end. So even the code I'm submitting might stand some improvement but I hope it points you in the right direction. A rewarding exercise might be to create a function that takes the desired thisID as an argument instead of hard-coding it.

var found = _.filter(array, function(obj) {
    var hasId77 = _.filter(_.values(obj)[0].data, function(data) {
        return data.thisID == 77
    });

    if (!_.isEmpty(hasId77)) {
        return obj;
    }
});

console.log(JSON.stringify(found));

OUTPUT:

[  
   {  
      "15":{  
         "data":[  
            {  
               "thisID":"66"
            },
            {  
               "thisID":"77"
            }
         ],
         "settings":{  
            "other":"other"
         }
      }
   }
]

Here's a way you could do it with reduce . It's the same length as your example, but your example doesn't account for one layer of nesting. This assumes the outer most objects have only one key/value as all the objects in your example do.

var test_array = [{
  "12": {"data": [{"thisID": "44"},{"thisID": "55"}],
         "settings": {"other":"other"}}
}, {
  "15": {"data": [{"thisID": "66"},{"thisID": "77"}],
         "settings": {"other":"other"}}
}];
var found = _.reduce(test_array, function(memo, inner_object) {
    var data = _.values(inner_object)[0].data
    return memo.concat(_.where(data, {thisID: "77"}));
}, []);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM