Search code examples
javascriptarraysalgorithmobjecthashtable

sum array of objects inside an array of objects


I have an array of objects and inside the array there is another array of objects, I would like to sum the values. So the sum is based on the same picker_id. Then sum current_capacity, process_time_in_minutes, and picked_qty inside products which is array of objects. Here is my data:

var arr = [
  {
    current_capacity: 6000,
    picker_id: "icQrHPuE2fMZslceSG6liwuRar92",
    process_time_in_minutes: 10,
    products: [
      {
        product_id: 1,
        picked_qty: 2
      },
      {
        product_id: 2,
        picked_qty: 3
      }
    ]
  },

  {
    current_capacity: 2500,
    picker_id: "icQrHPuE2fMZslceSG6liwuRar92",
    process_time_in_minutes: 20,
    products: [
      {
        product_id: 1,
        picked_qty: 10
      }
    ]
  },

  {
    current_capacity: 36000,
    picker_id: "WIRzfIZALeftRk3DRGvh4nBdxQV2",
    process_time_in_minutes: 15,
    products: [
      {
        product_id: 1,
        picked_qty: 2
      },
      {
        product_id: 2,
        picked_qty: 3
      }
    ]
  }
];

Here is my code:

  var res = arr.reduce((acc, obj) => {
  var existObj = acc.find((item) => item.picker_id === obj.picker_id);
  if (existObj) {
    let total_picked = obj.products.reduce((acc2, curr) => acc2 + curr);

    // console.log("total_picked", total_picked);
    existObj.current_capacity =
      existObj.current_capacity + obj.current_capacity;
    existObj.process_time_in_minutes =
      existObj.process_time_in_minutes + obj.process_time_in_minutes;

    existObj.total = existObj.total ? existObj.total : 0 + total_picked;
    return acc;
  }
  acc.push(obj);
  return acc;
}, []);

const formatted = res.map((el) => {
  return {
    picker_id: el.picker_id,
    total_volume: el.current_capacity,
    total_time: el.process_time_in_minutes,
    total_products: el.total
  };
});

The result is as below:

[
 {
   picker_id: "icQrHPuE2fMZslceSG6liwuRar92"
   total_volume: 8500
   total_time: 30
   total_products: "0[object Object]"
 },
 {
   picker_id: "WIRzfIZALeftRk3DRGvh4nBdxQV2"
   total_volume: 36000
   total_time: 15
   total_products: undefined
  }
]

Expected like below:

[
 {
   picker_id: "icQrHPuE2fMZslceSG6liwuRar92"
   total_volume: 8500
   total_time: 30
   total_products: 15
 },
 {
   picker_id: "WIRzfIZALeftRk3DRGvh4nBdxQV2"
   total_volume: 36000
   total_time: 15
   total_products: 5
  }
]

Solution

  • Using a little parameter destructuring, I think you can do a little further clean-up after you fix the problems others have described. My version might look like this:

    const extract = (xs) => Object .values (xs .reduce (
      (acc, {current_capacity, picker_id, process_time_in_minutes, products}) => {
        const curr = acc [picker_id] || (acc [picker_id] = {
          picker_id, total_volume: 0, total_time: 0, total_products: 0
        })
        curr .total_volume += current_capacity
        curr .total_time += process_time_in_minutes
        curr .total_products += products .reduce ((t, p) => t + p .picked_qty, 0)
        return acc
      },
      {}
    ))
    
    const arr = [{current_capacity: 6e3, picker_id: "icQrHPuE2fMZslceSG6liwuRar92", process_time_in_minutes: 10, products: [{product_id: 1, picked_qty: 2}, {product_id: 2, picked_qty: 3}]}, {current_capacity: 2500, picker_id: "icQrHPuE2fMZslceSG6liwuRar92", process_time_in_minutes: 20, products: [{product_id: 1, picked_qty: 10}]}, {current_capacity: 36e3, picker_id: "WIRzfIZALeftRk3DRGvh4nBdxQV2", process_time_in_minutes: 15, products: [{product_id: 1, picked_qty: 2}, {product_id: 2, picked_qty: 3}]}]
    
    console .log (extract (arr))
    .as-console-wrapper {max-height: 100% !important; top: 0}