简体   繁体   中英

Extract object attribute from list of objects in Javascript

I have the following object that I'm receiving from an API:

{
   '2012-12-12': [
       { 'id': 1234,
         'type': 'A' },
       { 'id': 1235,
         'type': 'A' },
       { 'id': 1236,
         'type': 'B' },
    ],
   '2012-12-13': [
       { 'id': 1237,
         'type': 'A' },
       { 'id': 1238,
         'type': 'C' },
       { 'id': 1239,
         'type': 'B' },
    ]
}

Then I want to have another variable named types of type Array that will hold every possible value of the type attribute of each one of the objects. In this case it would be:

types = ['A', 'B', 'C']

I'm trying to have it done in a functional way (I'm using underscore.js) but I'm unable to figure out a way of doing it. Right now I'm using

types = [];
_.each(response, function(arr1, key1) {
    _.each(arr1, function(arr2, key2) {
        types.push(arr2.type);
    });
});
types = _.uniq(types);

But that's very ugly. Can you help me in figuring out a better way of writing this code?

Thanks!

This should work:

types = _.chain(input) // enable chaining
  .values()            // object to array
  .flatten()           // 2D array to 1D array
  .pluck("type")       // pick one property from each element
  .uniq()              // only the unique values
  .value()             // get an unwrapped array

Fiddle: http://jsfiddle.net/NFSfs/

Of course, you can remove all whitespace if you want to:

types = _.chain(input).values().flatten().pluck("type").uniq().value()

or without chaining:

types = _.uniq(_.pluck(_.flatten(_.values(input)),"type"));

flatten seems to work on objects , even though the documentation clearly states it shouldn't . If you wish to code against implementation, you can leave out the call to values , but I don't recommend that. The implementation could change one day, leaving your code mysteriously broken.

If you just want shorter code, you could flatten the objects into a single Array, then map that Array.

var types = _.unique(_.map(_.flatten(_.toArray(response)), function(arr) {
    return arr.type;
}));

Here's another version. Mostly just for curiosity's sake.

var types = _.unique(_.pluck(_.reduce(response, _.bind(Function.apply, [].concat), []), "type"));

Here's another one.

var types = _.unique(_.reduce(response, function(acc, arr) {
    return acc.concat(_.pluck(arr,"type"));
}, []));

And another.

var types = _.unique(_.pluck([].concat.apply([], _.toArray(response)), "type"))

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