How to combine values in array by key?

103 views Asked by At

I have data that looks like this:

data = [
  [
    {"name":"cpumhz","data":[[1433856538,0],[1433856598,0]]},
    {"name":"mem","data":[[1433856538,13660],[1433856598,13660]]}
  ],
  [
    {"name":"cpumhz","data":[[1433856538,0],[1433856598,0]]},
    {"name":"mem","data":[[1433856538,13660],[1433856598,13660]]}
  ],
  [
    {"name":"cpumhz","data":[[1433856538,0],[1433856598,0]]},
    {"name":"mem","data":[[1433856538,13660],[1433856598,13660]]}
  ]
];

how would I use map to combine the array items so the data attributes are concatenated?

Like so:

data = [
  [
    {"name":"cpumhz","data":[[1433856538,0],[1433856598,0],[1433856538,0],[1433856598,0], [1433856538,0],[1433856598,0]]},
    {"name":"mem","data":[[1433856538,13660],[1433856598,13660], [1433856538,13660],[1433856598,13660], [1433856538,13660],[1433856598,13660]]}
  ]
];

I'm getting closer by doing it non-programatically like so:

res = []

cpudata = _.flatten([data[0][0].data, data[1][0].data, data[2][0].data])
res.push({name: 'cpumhz', data: cpudata})

memdata = _.flatten([data[0][1].data, data[1][1].data, data[2][1].data])
res.push({name: 'mem', data: memdata})

http://jsbin.com/bekodirili/7/edit

2

There are 2 answers

0
wjohnsto On BEST ANSWER

Look into using the reduce function. Underscore/lodash have equivalent functions.

Essentially you want to take data and reduce it down to 1 array with 2 values. Something like the following should work:

var reducedData = data.reduce(function(prev, cur) {
    prev.forEach(function(value, index) {
        value.data = value.data.concat(cur[index].data);
    });

    return prev;
});

You go over each value in data and reduce it. You concat the previous sub-data with the current sub-data and return the new value.

0
Adam Boduch On

With lodash, you can do something like this:

_(data)
    .flatten()
    .groupBy('name')
    .reduce(function(result, item, key) {
        return result.concat([{
            name: key,
            data: _.flatten(_.pluck(item, 'data'))
        }]);
    }, []);

You use flatten() to create an array that can then be grouped into an object, based on the name value using groupBy(). At this point, you have an object with two properties - cpuhz and mem.

Now it's easy to reduce() the object into the array you want.