I've looked at lots of examples but cannot get this to work. At best, I end up with a version of the existing array with properties replicated that should be lost in the summary.
I would like to output a new array of totals for each location and not include any details for specific periods, the period property etc. I think my issue is with Object.assign({}, o); where I am creating a full copy, but I can't see how to just create an object with just the location, to which the totals can be added.
This is a simplified example and in the original I am summing multiple columns and dropping multiple columns.
let helper = {};
let locationPeriodCounts = [
{"period": "2023-10-21", "location": "228", "countIn": 6, "countOut": 1},
{"period": "2023-10-22", "location": "228", "countIn": 8, "countOut": 2},
{"period": "2023-10-23", "location": "228", "countIn": 3, "countOut": 3},
{"period": "2023-10-24", "location": "228", "countIn": 1, "countOut": 4},
{"period": "2023-10-21", "location": "229", "countIn": 5, "countOut": 6},
{"period": "2023-10-22", "location": "229", "countIn": 18, "countOut": 6},
{"period": "2023-10-23", "location": "229", "countIn": 8, "countOut": 6},
{"period": "2023-10-24", "location": "230", "countIn": 3, "countOut": 6},
{"period": "2023-10-25", "location": "230", "countIn": 4, "countOut": 6}
];
let locationCounts = locationPeriodCounts.reduce(function(r, o) {
let key = o.location;
if (!helper[key]) {
helper[key] = Object.assign({}, o); // create a copy of o
helper[key].totalCountIn = 0;
helper[key].totalCountOut = 0;
r.push(helper[key]);
} else {
helper[key].totalCountIn += o.countIn;
helper[key].totalCountOut += o.countOut;
}
return r;
}, []);
console.log(locationCounts);
This is what I'm looking for as output...
[
{"location": "228", "totalCountIn": 18, "totalCountOut": 10},
{"location": "229", "totalCountIn": 31, "totalCountOut": 18},
{"location": "230", "totalCountIn": 7, "totalCountOut": 12}
];
I added an Object.entries to convert to object array
We now need to spread the nested object to have both counters on the same level as the location
let locationCounts = Object.entries(
locationPeriodCounts
.reduce(function (acc, { location, countIn, countOut }) {
acc[location] ??= { totalCountIn: 0, totalCountOut: 0 }; // create if it does not exist
acc[location].totalCountIn += countIn; // always add to the total
acc[location].totalCountOut += countOut; // always add to the total
return acc;
}, {})
)
.map(([location, { totalCountIn, totalCountOut }]) => ({ location, totalCountIn, totalCountOut }));
console.log(locationCounts);
<script>
let locationPeriodCounts = [
{"period": "2023-10-21", "location": "228", "countIn": 6, "countOut": 1},
{"period": "2023-10-22", "location": "228", "countIn": 8, "countOut": 2},
{"period": "2023-10-23", "location": "228", "countIn": 3, "countOut": 3},
{"period": "2023-10-24", "location": "228", "countIn": 1, "countOut": 4},
{"period": "2023-10-21", "location": "229", "countIn": 5, "countOut": 6},
{"period": "2023-10-22", "location": "229", "countIn": 18, "countOut": 6},
{"period": "2023-10-23", "location": "229", "countIn": 8, "countOut": 6},
{"period": "2023-10-24", "location": "230", "countIn": 3, "countOut": 6},
{"period": "2023-10-25", "location": "230", "countIn": 4, "countOut": 6}
];
</script>