Question

Using preferably Lo-Dash or Underscore methods, is there a way to "merge" an array of like objects' values?

For example, I would like to take an array like this . . .

[
  {x: 1, y: 2, z: 3},
  {x: 4, y: 5, z: 6}
]

. . . and transform it into this . . .

{
  x: [1, 4],
  y: [2, 5],
  z: [3, 6]
}
Was it helpful?

Solution 2

I am sure this is what you are going for

var data = [{x: 1, y: 2, z: 3}, {x: 4, y: 5, z: 6}];

console.log(_.merge(data[0], data[1], function(a, b) {
    return [a, b];
}));
# { x: [ 1, 4 ], y: [ 2, 5 ], z: [ 3, 6 ] }

For N objects in an array,

var data = [{x: 1, y: 2, z: 3}, {x: 4, y: 5, z: 6}, {x: 7, y: 8, z: 9}];

console.log(_.merge.apply(null, data.concat(function(a, b) {
    return _.isArray(a) ? a.concat(b): [a, b];
})));
# { x: [ 1, 4, 7 ], y: [ 2, 5, 8 ], z: [ 3, 6, 9 ] }

OTHER TIPS

Using Underscore:

var input = [
  {x: 1, y: 2, z: 3},
  {x: 4, y: 5, z: 6}
];

var output = {};

for(var k in input[0]) {
    output[k] = _.keys(_.groupBy(input, function(value) {
        return value[k];
    }));
}

console.log(output);

Console output:

v Object {x: Array[2], y: Array[2], z: Array[2]}
  v x: Array[2]
    0: "1"
    1: "4"
    length: 2
    __proto__: Array[0]
  v y: Array[2]
    0: "2"
    1: "5"
    length: 2
    __proto__: Array[0]
  v z: Array[2]
    0: "3"
    1: "6"
    length: 2
    __proto__: Array[0]
  __proto__: Object

jsfiddle

A plain JS solution:

var input = [
  {x: 1, y: 2, z: 3},
  {x: 4, y: 5, z: 6}
];

var output = { };
input.forEach(function(item){
  for (var key in item) {
    if (!output[key]) output[key] = [ item[key] ];
    else output[key].push(item[key]);
  }
});

You could use

var input = [
  {x: 1, y: 2, z: 3},
  {x: 4, y: 5, z: 6}
];
var output = input.reduce(function(output, item){
  for (var key in item) { if (item.hasOwnProperty(key)) {
    if (!output[key]) output[key] = [ item[key] ];
    else output[key].push(item[key]);
  } }
  return output;
}, {});

(based on @Tibos answer, but using reduce instead of forEach, and checking hasOwnProperty).

Has-been while solution. Let's say that your array is bound to a variable called source :

var o = {},
    i = 0,
    item, k;
while (item = source[i++]) {
    for (k in item) {
        if (!o[k]) o[k] = [item[k]];
        else o[k].push(item[k]);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top