awesome_treehouse
awesome_treehouse

Reputation: 77

Trying to reduce an array of objects to a similar but summed up array of objects

So I have an array of objects that looks like:

dataArray = [
    {Revenue: 5, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 10, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 5, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 1, Date: "2018-06-13T00:00:00", DateString: "6/13/2018"},
    {Revenue: 4, Date: "2018-06-13T00:00:00", DateString: "6/13/2018"}
]

And what I need is to reduce that down to another array of objects that looks like:

reducedDataArray = [
    {Revenue: 20, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 5, Date: "2018-06-13T00:00:00", DateString: "6/13/2018"}
]

Basically if the date is the same then the revenue needs to be summed up so that there aren't multiple instances of the same date. Unfortunately I am limited to our version of Typescript so I don't have all the cool ES6 goodies to help with this stuff. I've tried using things like reduce() but I think a combination of not knowing what the heck I'm doing and this being kind of weird has left me in a fog.

Any suggestions or insight would be greatly appreciated!

Upvotes: 1

Views: 74

Answers (2)

Liang
Liang

Reputation: 515

Played with some loops and it works

dataArray = [
    {Revenue: 5, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 10, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 5, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 1, Date: "2018-06-13T00:00:00", DateString: "6/13/2018"},
    {Revenue: 4, Date: "2018-06-13T00:00:00", DateString: "6/13/2018"}
];

const getUnique=array=>{
  return array.filter((value, index, self)=> { 
      return self.indexOf(value) === index;
  });
}

let date=[];
let output=[];

for(const v of dataArray) date.push(v.Date);
for(const v of getUnique(date)){

  let revenue=0,date=v,dateString;
  for(const x of dataArray){
    if(x.Date==v) revenue+=x.Revenue;
    dateString=x.DateString;
  }

  output.push({
    Revenue:revenue,
    Date:v,
    DateString:dateString
  });

}

console.log(output);

jsfiddle link

Upvotes: 1

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249536

You can use reduce to create an object with date keys and then convert the object back to an array.

let dataArray = [
    {Revenue: 5, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 10, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 5, Date: "2018-06-05T00:00:00", DateString: "6/5/2018"},
    {Revenue: 1, Date: "2018-06-13T00:00:00", DateString: "6/13/2018"},
    {Revenue: 4, Date: "2018-06-13T00:00:00", DateString: "6/13/2018"}
]
// We need to specify the type parameter explicitly, as it will not be inffered from initial value 
let valuesObj = dataArray.reduce<{ [date: string]: typeof dataArray[number] }>((p, v) => {
    const existing = p[v.Date];
    if (existing) {
        existing.Revenue += v.Revenue
    } else {
        p[v.Date] = Object.assign({}, v); //Create a copy so as to not change the original when we sum 
    }
    return p;
}, {});


// You can use Object.values(valuesObj) if available 
let values = Object.keys(valuesObj).map(k => valuesaObj[k]);

Playground link

Upvotes: 3

Related Questions