简体   繁体   中英

Combine the attributes of an array of objects in Javascript

I have this dataset:

var dataset = [
{time: "t1", val1: 0, val2: 0, val3: 1},
{time: "t2", val1: 0, val2: 0, val3: 4},
{time: "t3", val1: 1, val2: 0, val3: 0},
{time: "t4", val1: 3, val2: 0, val3: 0},
{time: "t2", val1: 0, val2: 3, val3: 0},
{time: "t4", val1: 0, val2: 2, val3: 0},
{time: "t5", val1: 2, val2: 0, val3: 0},

....
];

I want to reduce the dataset to uniques time entries but also combine the values per timestep. The result must look like this:

var dataset = [
{time: "t1", val1: 0, val2: 0, val3: 1},
{time: "t2", val1: 0, val2: 3, val3: 4},
{time: "t3", val1: 1, val2: 0, val3: 0},
{time: "t4", val1: 3, val2: 2, val3: 0},
{time: "t5", val1: 2, val2: 0, val3: 0},
....
];

I tried someting with the reduce() method based on other SO posts:

dataset.reduce(function(r,o){
var key = o.Date;
var newObj = o;
if (r[key] || (r[key]=[])) r[key].push(o);
  return r;
}, []);

console.log(dataset);

It reduces the dataset to 5 entries, but the structure isn't exactly how I want it and I don't know how to combine the object values.

Any help is appreciated.

Array.reduce() variation:

 var dataset = [ {time: "t1", val1: 0, val2: 0, val3: 1}, {time: "t2", val1: 0, val2: 0, val3: 4}, {time: "t3", val1: 1, val2: 0, val3: 0}, {time: "t4", val1: 3, val2: 0, val3: 0}, {time: "t5", val1: 2, val2: 0, val3: 0}, {time: "t2", val1: 0, val2: 3, val3: 0}, {time: "t4", val1: 0, val2: 2, val3: 0} ], result = []; dataset.reduce(function(r, o){ var k = o.time; // crucial key (used for grouping entries) if (r[k]) { r[k].val1 +=o.val1; r[k].val2 +=o.val2; r[k].val3 +=o.val3; } else { result.push(o); r[k] = o; } return r; }, {}); console.log(result); 

You can save the time values on each iteration step into a temporary keys property:

var dataset = [
    { time: "t1", val1: 0, val2: 0, val3: 1 },
    { time: "t2", val1: 0, val2: 0, val3: 4 },
    { time: "t3", val1: 1, val2: 0, val3: 0 },
    { time: "t4", val1: 3, val2: 0, val3: 0 },
    { time: "t5", val1: 2, val2: 0, val3: 0 },
    { time: "t2", val1: 0, val2: 3, val3: 0 },
    { time: "t4", val1: 0, val2: 2, val3: 0 },
];

var newData = dataset.reduce(function (r, o) {
    if (r.keys[o.time] !== true) {
        r.data.push(o);
    }
    r.keys[o.time] = true;
    return r;
}, { data: [], keys: {} }).data;

console.log(newData);
//[ { time: 't1', val1: 0, val2: 0, val3: 1 },
//  { time: 't2', val1: 0, val2: 0, val3: 4 },
//  { time: 't3', val1: 1, val2: 0, val3: 0 },
//  { time: 't4', val1: 3, val2: 0, val3: 0 },
//  { time: 't5', val1: 2, val2: 0, val3: 0 } ]

You can use Array methods like the example

 var dataset = [ {time: "t1", val1: 0, val2: 0, val3: 1}, {time: "t2", val1: 0, val2: 0, val3: 4}, {time: "t3", val1: 1, val2: 0, val3: 0}, {time: "t4", val1: 3, val2: 0, val3: 0}, {time: "t5", val1: 2, val2: 0, val3: 0}, {time: "t2", val1: 0, val2: 3, val3: 0}, {time: "t4", val1: 0, val2: 2, val3: 0} ]; var datasetReduced=[]; dataset.forEach(function(dataItem){ var reducedItem = datasetReduced.find(function(element){ return element.time === dataItem.time; }); if(reducedItem){ reducedItem.val1= reducedItem.val1 + dataItem.val1; reducedItem.val2= reducedItem.val2 + dataItem.val2; reducedItem.val3= reducedItem.val3 + dataItem.val3; }else{ datasetReduced.push(dataItem); } }); console.log(datasetReduced); 

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