Home > Software design >  Javascript: Create cumulative objects for consecutive months and then reset each year
Javascript: Create cumulative objects for consecutive months and then reset each year

Time:11-28

I have a dataset that looks like this:

const data = [
 {num: 3, date: 2010-01-01, month: "January", year: 2010}, 
 {num: 10, date: 2010-01-02, month: "January", year: 2010}, 
 {num: 2, date: 2010-01-03, month: "January", year: 2010},
 {num: 0.1, date: 2010-01-04, month: "January", year: 2010},
 {num: 0, date: 2010-01-05, month: "January", year: 2010},
 {num: 13, date: 2010-02-01, month: "February", year: 2010},
 {num: null, date: 2010-02-02, month: "February", year: 2010},
 {num: null, date: 2010-02-03, month: "February", year: 2010},
 {num: 2, date: 2010-02-04, month: "February", year: 2010},
 {num: 3, date: 2010-02-05, month: "February", year: 2010},
 {num: 0.1, date: 2010-03-01, month: "March", year: 2010},
 {num: 0.002, date: 2010-03-02, month: "March", year: 2010},
 {num: 4, date: 2010-03-03, month: "March", year: 2010},
 {num: 4.1, date: 2010-03-04, month: "March", year: 2010},
 {num: 6, date: 2010-03-05, month: "March", year: 2010},
 {num: 6.7, date: 2011-01-01, month: "January", year: 2011}, 
 {num: 2, date: 2011-01-02, month: "January", year: 2011}, 
 {num: 2.2, date: 2011-01-03, month: "January", year: 2011},
 {num: 3, date: 2011-01-04, month: "January", year: 2011},
 {num: null, date: 2011-01-05, month: "January", year: 2011},
 {num: 0, date: 2011-02-01, month: "February", year: 2011},
 {num: 0, date: 2011-02-02, month: "February", year: 2011},
 {num: 2.1, date: 2011-02-03, month: "February", year: 2011},
 {num: 0, date: 2011-02-04, month: "February", year: 2011},
 {num: 0, date: 2011-02-05, month: "February", year: 2011},
 {num: null, date: 2011-03-01, month: "March", year: 2011},
 {num: 2.1, date: 2011-03-02, month: "March", year: 2011},
 {num: 4, date: 2011-03-03, month: "March", year: 2011},
 {num: 9, date: 2011-03-04, month: "March", year: 2011},
 {num: 7.8, date: 2011-03-05, month: "March", year: 2011},
]

It keeps going up until 2020.

I want to arrange this dataset so that it cumulates until the end of each year, and it resets again when a new year begins.

So something like this (apologies if my addition math is wrong -- just doing this out by hand):

[
 {year: 2010, month: "January", total: 15.1},
 {year: 2010, month: "February", total: 33.1}, //15.1 18
 {year: 2010, month: "March", total: 47.302}, //15.1 18 14.202
 {year: 2011, month: "January", total: 13.9}, // resets -- doesn't cumulate from last year
 {year: 2011, month: "February", total: 16 }, // 13.9   2.1
 {year: 2011, month: "March", total: 38.9}, //13.9   2.1   22.9
]

I'm learning about the reduce method in Javascript and I'm trying to use it but can only accomplish an output like this. It's close, in that it's summing the days in the month, but not quite there yet. Any help or advice would be appreciated.

data.reduce((acc, curr) => {
    if (curr.num === null ) return acc
    for ( const e of acc) {
        if (e.year === curr.year && e.month === curr.month) {
            e.totalSum  = curr.num
            return acc
        }
    }
    const y = {
        year: curr.year, 
        month: curr.month, 
        total: curr.num
    }
    return state.concat([y])
}, [])

which results in this:

[
 {year: 2010, month: "January", total: 15.1},
 {year: 2010, month: "February", total: 18}, 
 {year: 2010, month: "March", total: 14.202},
 {year: 2011, month: "January", total: 13.9},
 {year: 2011, month: "February", total: 2.1 },
 {year: 2011, month: "March", total: 22.9},
]

Again, this is sort of close, but I'd like the consecutive months to cumulate. Any help or advice would be appreciated.

CodePudding user response:

You can simplify it to:

const data = [
    {num: 3, date: 2010-01-01, month: "January", year: 2010},
    {num: 10, date: 2010-01-02, month: "January", year: 2010},
    {num: 2, date: 2010-01-03, month: "January", year: 2010},
    {num: 0.1, date: 2010-01-04, month: "January", year: 2010},
    {num: 0, date: 2010-01-05, month: "January", year: 2010},
    {num: 13, date: 2010-02-01, month: "February", year: 2010},
    {num: null, date: 2010-02-02, month: "February", year: 2010},
    {num: null, date: 2010-02-03, month: "February", year: 2010},
    {num: 2, date: 2010-02-04, month: "February", year: 2010},
    {num: 3, date: 2010-02-05, month: "February", year: 2010},
    {num: 0.1, date: 2010-03-01, month: "March", year: 2010},
    {num: 0.002, date: 2010-03-02, month: "March", year: 2010},
    {num: 4, date: 2010-03-03, month: "March", year: 2010},
    {num: 4.1, date: 2010-03-04, month: "March", year: 2010},
    {num: 6, date: 2010-03-05, month: "March", year: 2010},
    {num: 6.7, date: 2011-01-01, month: "January", year: 2011},
    {num: 2, date: 2011-01-02, month: "January", year: 2011},
    {num: 2.2, date: 2011-01-03, month: "January", year: 2011},
    {num: 3, date: 2011-01-04, month: "January", year: 2011},
    {num: null, date: 2011-01-05, month: "January", year: 2011},
    {num: 0, date: 2011-02-01, month: "February", year: 2011},
    {num: 0, date: 2011-02-02, month: "February", year: 2011},
    {num: 2.1, date: 2011-02-03, month: "February", year: 2011},
    {num: 0, date: 2011-02-04, month: "February", year: 2011},
    {num: 0, date: 2011-02-05, month: "February", year: 2011},
    {num: null, date: 2011-03-01, month: "March", year: 2011},
    {num: 2.1, date: 2011-03-02, month: "March", year: 2011},
    {num: 4, date: 2011-03-03, month: "March", year: 2011},
    {num: 9, date: 2011-03-04, month: "March", year: 2011},
    {num: 7.8, date: 2011-03-05, month: "March", year: 2011},
];

const res = data.reduce((acc, curr) => {
    if (curr.num === null ) return acc
    const last = acc[acc.length - 1];
    if(last?.month === curr.month){
        last.totalSum  = curr.num;
        return acc;
    }
    const y = {
        year: curr.year,
        month: curr.month,
        totalSum: curr.num   (curr.year === last?.year ? last.totalSum : 0)
    };
    return acc.concat([y])
}, []);

console.log(res);

and then it's just a matter of initializing y.totalSum

  • Related