Search code examples
javascriptlodash

How to group array data in object with count using lodash


How can I groupby data with count using lodash javascript

"data": [
            {
                "id": 27,
                "getOrderDetail": [
                    {
                        "id": 49,
                        "order_id": 27,
                        "product_id": 1,
                        "product_detail":[...some data...]
                    },
                    {
                        "id": 51,
                        "order_id": 27,
                        "product_id": 2,
                        "product_detail":[...some data...]
                    }
                    {
                        "id": 52,
                        "order_id": 27,
                        "product_id": 1,
                        "product_detail":[...some data...]
                    }
                ],
                "getOrderStatus": []
            },
        ]

I want to group by product_id in getOrderDetail and count it into qty for example

"data": [
            {
                "id": 27,
                "getOrderDetail": [
                    {
                        "id": 49,
                        "qty": 2,
                        "order_id": 27,
                        "product_id": 1,
                        "product_detail":[...some data...]
                    },
                    {
                        "id": 51,
                        "order_id": 27,
                        "qty": 1,
                        "product_id": 2,
                        "product_detail":[...some data...]
                    }
                ],
                "getOrderStatus": []
            },
        ]

I want to do something like this

_.countBy(data, 'getOrderDetail.product_id'); and put data count into qty field

Here is what I try

let result = _.map(totalData, function(totalData, key) {
        let mapData = _.groupBy(totalData.getOrderDetail, function({ product_id }) {
            return product_id;
        });
});

I console.log (mapData) output look like this

{
  '1': [
    {
      id: 49,
      product_id: 1,
    }
  ],
  '2': [
    {
      id: 51,
      product_id: 2,
    }
  ]
}

still find looking into how can I can conunt qty


Solution

  • You can use _.groupBy() and then map the results, and get the qty by applying _.size() to the group, and get getOrderDetail by merging the group members, concating the arrays, and spreading back to the object:

    const data = [{"id":27,"getOrderDetail":[{"id":49,"order_id":27,"product_id":1,"product_detail":[]},{"id":51,"order_id":27,"product_id":2,"product_detail":[]},{"id":52,"order_id":27,"product_id":1,"product_detail":[]}],"getOrderStatus":[]}];
    
    const result = data.map(o => ({
      ...o,
      getOrderDetail: _.map(
          _.groupBy(o.getOrderDetail, 'product_id'),
          group => ({
            qty: _.size(groups),
            ..._.mergeWith({}, ...groups, (ov, sv) =>
              _.isArray(ov) ? ov.concat(sv) : sv
            )
          })
      )
    }));
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>