简体   繁体   中英

Typescript/lodash: how to get results/objects with multiple common properties

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM