Home > database >  Creating an array of objects with cumulative sum in javascript
Creating an array of objects with cumulative sum in javascript

Time:08-28

I have this original array that i need to transform into the one named original.

const data =  [ {
end_date: "2020-01-31"
invoices_count: 22
month: "2020-01"
start_date: "2020-01-01"
total_margin: 1000
total_revenue: 1000
},
{
end_date: "2020-02-29"
invoices_count: 14
month: "2020-02"
start_date: "2020-02-01"
total_margin: 2000
total_revenue: 2000
}]

i need to accumulate the total_margin and total_revenue over time, so that the result is equal to the previous month current month value, so the resulting array will look like this :

const result =  [ {
end_date: "2020-01-31"
invoices_count: 22
month: "2020-01"
start_date: "2020-01-01"
total_margin: 1000
total_revenue: 1000
},
{
end_date: "2020-02-29"
invoices_count: 14
month: "2020-02"
start_date: "2020-02-01"
total_margin: 3000
total_revenue: 3000
}]

I wrote this function to do this, but its modifying the first value in the array as well( total_margin & total_margin at index 0 ) , and the numbers don't really add up to the correct value, i am not sure what i am doing wrong

export const getCumulativeValueMonth = (data: MonthlyRevenue[]): MonthlyRevenue[] => {
  const orderedData = _.orderBy(data, (o) => Date.parse(o.start_date), ['asc']);
  const accumulated = orderedData.map((x, i) => ({
    start_date: x.start_date,
    end_date: x.end_date,
    invoices_count: x.invoices_count,
    month: x.month,
    total_margin: data
      .slice(0, i   1)
      .map(({ total_margin }) => total_margin)
      .reduce((z, y) => z   y),
    total_revenue: data
      .slice(0, i   1)
      .map(({ total_revenue }) => total_revenue)
      .reduce((z, y) => z   y),
  }));
  return accumulated;
};

Any ideas what i did wrong?

Thank you!

CodePudding user response:

You could take a closure over the wanted cumulative sums and add the values and return a new object.

const
    original = [{ end_date: "2020-01-31", invoices_count: 22, month: "2020-01", start_date: "2020-01-01", total_margin: 1000, total_revenue: 1000 }, { end_date: "2020-02-29", invoices_count: 14, month: "2020-02", start_date: "2020-02-01", total_margin: 2000, total_revenue: 2000 }],
    result = original.map(((total_margin, total_revenue) => o => {
        total_margin  = o.total_margin;
        total_revenue  = o.total_revenue;
        return { ...o, total_margin, total_revenue };
    })(0, 0));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

res = data.reduce((acc, it) => {
    if (acc.length > 0) {
        let last = acc[acc.length-1];
        acc.push({...it, total_margin: it.total_margin   last.total_margin, total_revenue: it.total_revenue   last.total_revenue});
    } else {
        acc.push(it);
    }

    return acc;
}, []);
  • Related