Ach
Ach

Reputation: 155

How can I group array data in object using lodash javascript

I want to group data using lodash javscript. first I try to use groupBy machine_id then I sum the total value

Here is my data

const data = [
  {
    id: 1,
    machine_id: 1,
    work_id: 1,
    total: 10
  },
  {
    id: 2,
    machine_id: 1,
    work_id: 2,
    total: 15
  },
  {
    id: 3,
    machine_id: 2,
    work_id: 3,
    total: 10
  },
  {
    id: 4,
    machine_id: 1,
    work_id: 1,
    total: 15
  },
]

I want to group machine_id then I want to sum by machine_id and after that I want to sum total each work_id

I want to output like this

[
  {
      "machine_id": 1,
      "sum_total": 25
      "work_group": [
        // In this work group I want to sum total each work_id 
        {
          work_id: 1
          sum_total: 25
        },
          {
          work_id: 2
          sum_total: 15
        }
      ]
    },
    {
      "machine_id": 2,
      "sum_total": 10
      "work_group": [
        {
          work_id: 3
          sum_total: 10
        }
      ]
    },
]

This is what I try

let groupData = _(data)
.groupBy("machine_id")
.map((data, machine_id) => ({
    machine_id,
    sum_total: _.sumBy(data, item => Number(item.total_time))
}))
.value();

my output look like this :

[
  {
      "machine_id": 1,
      "sum_total": 25

    },
    {
      "machine_id": 2,
      "sum_total": 10

    },
]

How can I drill down sum by work_id

Upvotes: 0

Views: 92

Answers (2)

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

User reduce and Object.values will simplify

const data = [
  {
    id: 1,
    machine_id: 1,
    work_id: 1,
    total: 10
  },
  {
    id: 2,
    machine_id: 1,
    work_id: 2,
    total: 15
  },
  {
    id: 3,
    machine_id: 2,
    work_id: 3,
    total: 10
  },
  {
    id: 4,
    machine_id: 1,
    work_id: 1,
    total: 15
  }
];

const updated = Object.values(
  data.reduce((acc, curr) => {
    if (curr.machine_id in acc) {
      const work_group = [
        ...acc[curr.machine_id].work_group,
        { work_id: curr.work_id, sum_total: curr.total }
      ].reduce((wg_acc, wg_curr) => {
        wg_acc[wg_curr.work_id] =
          wg_curr.work_id in wg_acc
            ? {
                ...wg_acc[wg_curr.work_id],
                sum_total: wg_acc[wg_curr.work_id].sum_total + wg_curr.sum_total
              }
            : { ...wg_curr };
        return wg_acc;
      }, {});
      acc[curr.machine_id] = {
        ...acc[curr.machine_id],
        sum_total: acc[curr.machine_id].sum_total + curr.total,
        work_group: Object.values(work_group)
      };
    } else {
      acc[curr.machine_id] = {
        machine_id: curr.machine_id,
        sum_total: curr.total,
        work_group: [{ work_id: curr.work_id, sum_total: curr.total }]
      };
    }

    return acc;
  }, {})
);

console.log(updated);

Upvotes: 2

Harish
Harish

Reputation: 1911

You can try below approach

const data = [
  {
    id: 1,
    machine_id: 1,
    work_id: 1,
    total: 10
  },
  {
    id: 2,
    machine_id: 1,
    work_id: 2,
    total: 15
  },
  {
    id: 2,
    machine_id: 2,
    work_id: 3,
    total: 10
  }
]

const res = data.reduce((acc = [], obj) => {
    const data = acc.findIndex(d => d.machine_id === obj.machine_id)
    if(data > -1) {
      acc[data] = { ...data, sum_total: acc[data].sum_total + obj.total, work_group: [...acc[data].work_group, obj] }
    } else {
      acc.push({
          machine_id: obj.machine_id,
          sum_total: obj.total,
          work_group:[obj]
      })
    }
 return acc;

}, [])

console.log(res)

Upvotes: 1

Related Questions