Home > database >  Javascript: How to subtotal values in list of { value, date } by time period?
Javascript: How to subtotal values in list of { value, date } by time period?

Time:04-30

I have a list of objects like this:

const rawData = [
    {
        "quantity": 44000,
        "date": "2017-10-24"
    },
    {
        "quantity": 44000,
        "date": "2017-10-24"
    },
    {
        "quantity": 44000,
        "date": "2017-10-27"
    },
    {
        "quantity": 44000,
        "date": "2017-10-27"
    },
    {
        "quantity": 44000,
        "date": "2017-11-16"
    }
]

I want to sum the quantities that belong in the same time period. For instance, applying a monthly period, I would like to obtain a list like this:

dataTotalledByMonth:

[
    {
        "quantity": 176000,
        "period": "2017-10"
    },
    {
        "quantity": 44000,
        "period": "2017-11"
    }
]

I want to come up with a general solution that will allow me to switch to different periods (annually, weekly, quarterly, etc) and get the processed list dynamically.

CodePudding user response:

While @R4ncid's solution works, I have an idea for a simpler code, which I deem more easier to follow:

const rawData = [{
    "quantity": 44000,
    "date": "2017-10-24"
  },
  {
    "quantity": 44000,
    "date": "2017-10-24"
  },
  {
    "quantity": 44000,
    "date": "2017-10-27"
  },
  {
    "quantity": 44000,
    "date": "2017-10-27"
  },
  {
    "quantity": 44000,
    "date": "2017-11-16"
  }
];

const final = {};

rawData.forEach(row => {
  // take just the first 2 date elements (year   month)
  const period = row.date.split('-').slice(0, -1).join('-');
  if (final[period]) {
    final[period].quantity  = row.quantity;
  } else {
    final[period] = {
      period,
      quantity: row.quantity
    };

  }
});

console.log(final);
console.log(Object.values(final));

CodePudding user response:

something like this?

const rawData = [
    {
        "quantity": 44000,
        "date": "2017-10-24"
    },
    {
        "quantity": 44000,
        "date": "2017-10-24"
    },
    {
        "quantity": 44000,
        "date": "2017-10-27"
    },
    {
        "quantity": 44000,
        "date": "2017-10-27"
    },
    {
        "quantity": 44000,
        "date": "2017-11-16"
    }
]

const calculateTotal = keyExtractor => data => 
Object.values(data.reduce((res, item) => {
   const date = keyExtractor(item)
   return {
     ...res, 
     [date]: {
       ...res[date],
       date,
       quantity: (res[date]?.quantity || 0)   item.quantity
     }
   }
}, {})) 

const annualCalculateTotal = calculateTotal(({date}) => date.substring(0, 4))
const monthlyCalculateTotal = calculateTotal(({date}) => date.substring(0, 7))

const afterAndBeforedateKeyGenerator = date => item => new Date(date) > new Date(item.date)? `before ${date}`: `after ${date}` 

console.log(annualCalculateTotal(rawData))
console.log(monthlyCalculateTotal(rawData))

console.log(calculateTotal(afterAndBeforedateKeyGenerator('2017-10-27'))(rawData))

  • Related