1

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.

2
  • What if there would be three t3 objects and two of them contain e.g. val2 property. Which one should be used? Commented Sep 29, 2017 at 14:38
  • Then they should be summarized. Commented Sep 29, 2017 at 14:40

3 Answers 3

4

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);

Sign up to request clarification or add additional context in comments.

Comments

1

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 } ]

1 Comment

You aren't updating anything. It appears that you are just keeping the first time and getting rid of the duplicates.
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);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.