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