Reputation: 619
I have an array of objects like this
const statuses = [
{time: '21/1/1990', 'Status.sold': 8848},
{time: '21/1/1990', 'Status.reserved': 8804},
{time: '21/1/1991', 'Status.reserved': 8756},
{time: '21/1/1991', 'Status.sold': 8732},
{time: '21/1/1992', 'Status.killed': 8691},
{time: '21/1/1992', 'Status.sold': 8620},
{time: '21/1/1993', 'Status.held': 8511},
{time: '21/1/1993', 'Status.killed': 8511},
{time: '21/1/1994', 'Status.sold': 8498},
];
and what I am trying to achieve is to put all Status.
properties together and grouped by the time
property, which is common for all objects. So the final result will be like this
const statuses = [
{time: '21/1/1990', sold: 8848, killed: 0, reserved: 8804, held: 0},
{time: '21/1/1991', sold: 8732, killed: 0, reserved: 8756, held: 0},
{time: '21/1/1992', sold: 8620, killed: 8691, reserved: 0, held: 0},
{time: '21/1/1993', sold: 0, killed: 8511, reserved: 0, held: 8511},
{time: '21/1/1994', sold: 8498, killed: 0, reserved: 0, held: 0},
];
I have tried something like this
const result = statuses.map((obj) => {
return { ...obj,
sold: obj['Status.sold'] ? obj['Status.sold'] : 0,
reserved: obj['Status.reserved'] ? obj['Status.reserved'] : 0,
killed: obj['Status.killed'] ? obj['Status.killed'] : 0,
held: obj['Status.held'] ? obj['Status.held'] : 0
};
});
but I'm not sure how to group them by time
. How can I combine reduce method with this code? Thanks in advance!
Upvotes: 0
Views: 97
Reputation: 2193
Try this:
const statuses = [
{time: '21/1/1990', 'Status.sold': 8848},
{time: '21/1/1990', 'Status.reserved': 8804},
{time: '21/1/1991', 'Status.reserved': 8756},
{time: '21/1/1991', 'Status.sold': 8732},
{time: '21/1/1992', 'Status.killed': 8691},
{time: '21/1/1992', 'Status.sold': 8620},
{time: '21/1/1993', 'Status.held': 8511},
{time: '21/1/1993', 'Status.killed': 8511},
{time: '21/1/1994', 'Status.sold': 8498},
];
const result = [];
let obj = {};
for (let i = 0; i < statuses.length; i++) {
const status = statuses[i];
if (status.time != obj.time) {
if (i != 0) result.push(obj);
obj = {
time: status.time,
sold: 0,
reserved: 0,
killed: 0,
held: 0,
}
}
if (status['Status.sold']) obj.sold += status['Status.sold'];
if (status['Status.reserved']) obj.reserved += status['Status.reserved'];
if (status['Status.killed']) obj.killed += status['Status.killed'];
if (status['Status.held']) obj.held += status['Status.held'];
}
result.push(obj);
console.log(result);
Upvotes: 1
Reputation: 386654
You could take an object for grouping by time
.
const
statuses = [{ time: '21/1/1990', 'Status.sold': 8848 }, { time: '21/1/1990', 'Status.reserved': 8804 }, { time: '21/1/1991', 'Status.reserved': 8756 }, { time: '21/1/1991', 'Status.sold': 8732 }, { time: '21/1/1992', 'Status.killed': 8691 }, { time: '21/1/1992', 'Status.sold': 8620 }, { time: '21/1/1993', 'Status.held': 8511 }, { time: '21/1/1993', 'Status.killed': 8511 }, { time: '21/1/1994', 'Status.sold': 8498 }],
result = Object.values(statuses.reduce((r, { time, ...o }) => {
r[time] ??= { time, sold: 0, killed: 0, reserved: 0, held: 0 };
Object.entries(o).forEach(([k, v]) => r[time][k.slice(7)] += v);
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1