Home > Enterprise >  How to group by multiple values and sum an array of objects?
How to group by multiple values and sum an array of objects?

Time:07-10

I would like to group an array of objects by type thick width height and sum the amount in jQuery. How can I achieve this?

For example:

var array = [
  { type: "alu", thick : 1 ,width:1000, height:2000 , amount: 50 },
  { type: "alu", thick : 1 ,width:1000, height:2000, amount: 30 },
  { type: "alu", thick : 1.5 ,width:1000, height:2000, amount: 20 },
  { type: "metal", thick : 2 ,width:1500, height:3000, amount: 15 }
]

Should result in:

var array = [
  { type: "alu", thick : 1 ,width:1000, height:2000 , amount: 80 },
  { type: "alu", thick : 1.5 ,width:1000, height:2000, amount: 20 },
  { type: "metal", thick : 2 ,width:1500, height:3000, amount: 15 }
]

since all the type , thick , width and height match the should merge but still add the amounts

CodePudding user response:

You can do something like the below, using vanilla JS:

var array = [
  { type: "alu", thick: 1, width: 1000, height: 2000, amount: 50 },
  { type: "alu", thick: 1, width: 1000, height: 2000, amount: 30 },
  { type: "alu", thick: 1.5, width: 1000, height: 2000, amount: 20 },
  { type: "metal", thick: 2, width: 1500, height: 3000, amount: 15 }
];

const res = [];

const process = () =>
  array.forEach((r) => {
    const found = res.find(
      (a) =>
        a.type == r.type &&
        a.thick == r.thick &&
        a.width == r.width &&
        a.height == r.height
    );
    if (found) {
      found.amount  = r.amount;
    } else {
      res.push({ ...r });
    }
  });

process();
console.log(res);

Which returns:

[
    {
        "type": "alu",
        "thick": 1,
        "width": 1000,
        "height": 2000,
        "amount": 80
    },
    {
        "type": "alu",
        "thick": 1.5,
        "width": 1000,
        "height": 2000,
        "amount": 20
    },
    {
        "type": "metal",
        "thick": 2,
        "width": 1500,
        "height": 3000,
        "amount": 15
    }
]

Alternatively you can use reduce:

const res = array.reduce((acc, el) => {
  const found = acc.find(
    (a) =>
      a.type == el.type &&
      a.thick == el.thick &&
      a.width == el.width &&
      a.height == el.height
  );
  if (found) {
    found.amount  = el.amount;
  } else {
    acc.push({ ...el });
  }
  return acc;
}, []);

console.log(res);
  • Related