Joey Hipolito
Joey Hipolito

Reputation: 3166

Array of objects to object of property values

I have this data:

[
    {foo: 1, bar: a},
    {foo: 2, bar: b},
    {foo: 3, bar: c},
]

What's the simplest way to transform the data to something like

{
    customLabel1 : [1,2,3],
    customLabel2 : [a,b,c]
}

I come up with this

{
    customLabel1: data.map((a) => {return a.foo} ),
    customLabel2: data.map((a) => {return a.bar} )
}

Is there a simpler way to do this, or faster?

Upvotes: 0

Views: 61

Answers (4)

Ram
Ram

Reputation: 144689

The shorter syntax of the map call can be:

data.map(el => el.prop);

Having said that, I'd define a helper function for this:

function pluck(arr, props) {
   return Object.keys(props).reduce((ret, prop) => {
     ret[prop] = arr.map(el => el[props[prop]]);
     return ret;
   }, {});
} 

var ret = pluck(data, {
  customLabel1: 'foo',
  customLabel2: 'bar'
});

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386560

You could use an object for the key mapping and iterate then.

var data = [{ foo: 1, bar: 'a' }, { foo: 2, bar: 'b' }, { foo: 3, bar: 'c' }],
    labels = { customLabel1: 'foo', customLabel2: 'bar' },
    result = {};

data.forEach(a => Object.keys(labels).forEach(k => {
    result[k] = result[k] || [];
    result[k].push(a[labels[k]]);
}));

console.log(result);

Upvotes: 1

Borja Tur
Borja Tur

Reputation: 817

You can use this form if you dont know the keys

{
    customLabel1: data.map(function(element) { return element[Object.keys(element)[0]];}),
    customLabel2: data.map(function(element) { return element[Object.keys(element)[1]];})
}

Upvotes: 1

Rick Viscomi
Rick Viscomi

Reputation: 8852

If you want simpler, your code is already pretty close with fat arrow syntax. You can drop the parentheses and the return keyword:

{
    customLabel1: data.map(a => a.foo),
    customLabel2: data.map(a => a.bar)
}

If you want faster, I think you'll have to sacrifice some simplicity. As it's written, you're looping over data twice. If you iterated once, it would look something like this:

var data = [
    {foo: 1, bar: 'a'},
    {foo: 2, bar: 'b'},
    {foo: 3, bar: 'c'},
];

var o = {customLabel1: [], customLabel2: []};
data.forEach(a => {
  o.customLabel1.push(a.foo);
  o.customLabel2.push(a.bar);
});
console.log(o);

Upvotes: 1

Related Questions