Home > Software engineering >  sum array of objects inside an array of objects
sum array of objects inside an array of objects

Time:11-17

Hi can anyone help me to for this problem, so 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
  }
]

CodePudding user response:

Issue with your implementation was if the existObj doesn't exit in your acc, you were directly pushing the obj instead you need to process the total first from the inner array of products.

I have updated your code to look cleaner and maintainable.

Approach:

  1. build a dict for each picker_id which hold the computed data
  2. convert dict to list
var result = arr.reduce((acc, obj) => {
  if (!acc[obj.picker_id]) {
    acc[obj.picker_id] = {
      total_volume: 0,
      total_time: 0,
      total_products: 0
    };
  }

  const selectedPicker = acc[obj.picker_id];
  const total_picked = obj.products.reduce((acc2, item) => acc2   item.picked_qty, 0);

  selectedPicker.total_volume = selectedPicker.total_volume   obj.current_capacity;
  selectedPicker.total_time =
    selectedPicker.total_time   obj.process_time_in_minutes;
  selectedPicker.total_products = selectedPicker.total_products   total_picked;
  
  return acc;
}, {});


const formatted = Object.keys(result).reduce((acc, picker_id) => {
    acc.push({
    picker_id,
    ...result[picker_id]
  })
    return acc;
}, [])

console.log("formmated", formatted);

Hope that helps.

Thanks

CodePudding user response:

You can also achieve your output by this


    function getProductQty(arr){
      let total = 0;
      arr.forEach(prd => {
        total  = prd.picked_qty
      })
      return total;
    }
    const result = arr.reduce((acc,product) => {
       if(!acc.hasOwnProperty(product.picker_id)){
          acc[product.picker_id] = {
            picker_id: product.picker_id,
            total_volume: product.current_capacity,
            total_time: product.process_time_in_minutes
       }    
             
      acc[product.picker_id].total_products = getProductQty(product.products);
      }else{
         acc[product.picker_id].total_volume = acc[product.picker_id].total_volume   product.current_capacity
         acc[product.picker_id].total_time = acc[product.picker_id].total_time   product.process_time_in_minutes
         acc[product.picker_id].total_products = acc[product.picker_id].total_products   getProductQty(product.products);
      }
          
         return acc
       },{})
        
        
console.log(Object.values(result),'result');

  • Related