I am looking for a lodash/typerscript solution for a groupBy function with multiple properties. Here's what I have tried so far:
JSON:
[
{
"jobId": 1001,
"id": 1,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1001,
"id": 2,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1002,
"id": 1,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1002,
"id": 1,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 2,
"balance": 100
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 2,
"balance": 100
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 2,
"balance": 100
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 2,
"balance": 100
}
]
Typescript code:
// Group of same ids
let mergeResults = _.groupBy(this.BSSDealresults, function (n) {
return n.timeSegmentId;
});
const objKeys = Object.keys(mergeResults);
const AggregateResults = [];
objKeys.forEach(item => {
if (mergeResults[item].length > 1) {
let agg_balance = 0;
mergeResults[item].forEach(element => {
agg_balance += element.balance;
});
AggregateResults.push({
id: mergeResults[item][0].id,
jobId: mergeResults[item][0].jobId,
balance: agg_balance
});
} else {
AggregateResults.push(mergeResults[item][0]);
}
})
This solution is giving aggragation of balance grouped by only same "id" as I have applied a lodash "_groupBy" funtion based on a property "id".
Whereas I am looking for aggregate results based on multiple properties e.g. id, jobId and timeSegId.
Is there any way in lodash/typescript where we can apply grouby using multiple properties?
The expected output should be:
[
{
"jobId": 1001,
"id": 1,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1001,
"id": 2,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1002,
"id": 1,
"timeSegmentId": 1,
"balance": 200
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 1,
"balance": 100
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 2,
"balance": 100
},
{
"jobId": 1003,
"id": 1,
"timeSegmentId": 2,
"balance": 300
}
]
You can generate a key for _.groupBy()
by creating a string out of the 3 ids. Then you can _.map()
the groups BSSDealresults
object, clone the 1st element using object spread (or Object.assign()
, and get the combined balance with _.sumBy()
:
const BSSDealresults = [{"jobId":1001,"id":1,"timeSegmentId":1,"balance":100},{"jobId":1001,"id":2,"timeSegmentId":1,"balance":100},{"jobId":1002,"id":1,"timeSegmentId":1,"balance":100},{"jobId":1002,"id":1,"timeSegmentId":1,"balance":100},{"jobId":1003,"id":1,"timeSegmentId":1,"balance":100},{"jobId":1003,"id":1,"timeSegmentId":2,"balance":100}];
const mergeResults = _.groupBy(BSSDealresults, ({ id, jobId, timeSegmentId }) => `${id}-${jobId}-${timeSegmentId}`);
const AggregateResults = _.map(mergeResults, group => ({
...group[0],
balance: _.sumBy(group, 'balance')
}));
console.log(AggregateResults);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>