Extract attribute of an object from a list of objects in Javascript
I have the following object that I receive from the 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
type Array
that will contain all possible attribute values type
for each of the objects. In this case it will be:
types = ['A', 'B', 'C']
I'm trying to do it in a functional way (I'm using underscore.js), but I can't figure out how. Right now I am using
types = [];
_.each(response, function(arr1, key1) {
_.each(arr1, function(arr2, key2) {
types.push(arr2.type);
});
});
types = _.uniq(types);
But this is very ugly. Can you help me design a better way to write this code?
Thank!
source to share
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/
You can of course remove all spaces if you like:
types = _.chain(input).values().flatten().pluck("type").uniq().value()
or without chaining:
types = _.uniq(_.pluck(_.flatten(_.values(input)),"type"));
anti-aliasing seems to work on objects , although the documentation clearly states it shouldn't . If you want to execute code versus implementation, you can leave the call values
, but I don't recommend doing that. The implementation can change one day, leaving your code mysteriously broken.
source to share
If you need shorter code, you can flatten the objects into one array and then display that array.
var types = _.unique(_.map(_.flatten(_.toArray(response)), function(arr) {
return arr.type;
}));
Here's another version. Mostly just for the sake of curiosity.
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 further.
var types = _.unique(_.pluck([].concat.apply([], _.toArray(response)), "type"))
source to share