How to Group by and Sum an Array of Objects

How to group by and sum an array of objects?

You can loop and sum it up

var array = [  { Id: "001", qty: 1 },   { Id: "002", qty: 2 },   { Id: "001", qty: 2 },   { Id: "003", qty: 4 }];
var result = [];array.reduce(function(res, value) { if (!res[value.Id]) { res[value.Id] = { Id: value.Id, qty: 0 }; result.push(res[value.Id]) } res[value.Id].qty += value.qty; return res;}, {});
console.log(result)

Javascript array of objects group and sum items

This works fine

Object.values(
cars.reduce((agg, car) => {
if (agg[car.make] === undefined) agg[car.make] = { make: car.make, sumQuantity: 0 }
agg[car.make].sumQuantity += +car.quantity
return agg
}, {})
)

Group by, and sum, and generate an object for each array in JavaScript

You can try this:

const result = Object.values(data.reduce((r, o) => (r[o.id]
? (r[o.id].total += o.total)
: (r[o.id] = {...o}), r), {}));

How to group by and sum an array of objects javascript?

You group the array into an object, where the keys are concatenation of available and id properties and finally transform the object back to an array using Object.values.

const 
array = [
{ data: { qty: "5", toy: { id: 3 }, available: "yes" } },
{ data: { qty: "5", toy: { id: 10 }, available: "no" } },
{ data: { qty: "59", toy: { id: 10 }, available: "yes" } },
{ data: { qty: "5", toy: { id: 3 }, available: "yes" } },
],
result = Object.values(
array.reduce((r, { data }) => {
const k = data.available + data.toy.id;
if (r[k]) {
r[k].data.qty = String(Number(r[k].data.qty) + Number(data.qty));
} else {
r[k] = { data };
}
return r;
}, {})
);

console.log(result);

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

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);

Applying group by and sum on array of objects in javascript

const myData = [
{
"siteDetails": {
"printerCode": "660103684",
"siteId": "UTT212303-STB-2040-0003"
},
"printingMaterialCode": "400000033",
"printingQuantity": 400,
"approved": true
},
{
"siteDetails": {
"printerCode": "660103684",
"siteId": "UTT212303-STB-2040-0002"
},
"printingMaterialCode": "400000033",
"printingQuantity": 600,
"campaignId": "DATAS00002",
},
{
"siteDetails": {
"printerCode": "660103684",
"siteId": "UTT212303-STB-2040-0001"
},
"printingMaterialCode": "400000034",
"printingQuantity": 300,
"campaignId": "DATAS00002",
}
]

function elaborateMyData(myData) {
const approvedQuantity = {};
const printingQuantity = {};
const myOutput = [];

myData.forEach((v) => {
printingQuantity[v.printingMaterialCode] = printingQuantity[v.printingMaterialCode] || 0;
approvedQuantity[v.printingMaterialCode] = approvedQuantity[v.printingMaterialCode] || 0;

printingQuantity[v.printingMaterialCode] += v.printingQuantity;

if (v.approved) {
approvedQuantity[v.printingMaterialCode] += v.printingQuantity
}

})

Object.keys(printingQuantity).forEach((v) => {
myOutput.push({
printingMaterialCode: v,
printingQuantity: printingQuantity[v],
approvedQuantity: approvedQuantity[v],
})
})

return myOutput
}

console.log(elaborateMyData(myData))

Group objects by multiple properties in array then sum up their values

Use Array#reduce with a helper object to group similar objects. For each object, check if the combined shape and color exists in the helper. If it doesn't, add to the helper using Object#assign to create a copy of the object, and push to the array. If it does, add it's values to used and instances.

var arr = [{"shape":"square","color":"red","used":1,"instances":1},{"shape":"square","color":"red","used":2,"instances":1},{"shape":"circle","color":"blue","used":0,"instances":0},{"shape":"square","color":"blue","used":4,"instances":4},{"shape":"circle","color":"red","used":1,"instances":1},{"shape":"circle","color":"red","used":1,"instances":0},{"shape":"square","color":"blue","used":4,"instances":5},{"shape":"square","color":"red","used":2,"instances":1}];
var helper = {};var result = arr.reduce(function(r, o) { var key = o.shape + '-' + o.color; if(!helper[key]) { helper[key] = Object.assign({}, o); // create a copy of o r.push(helper[key]); } else { helper[key].used += o.used; helper[key].instances += o.instances; }
return r;}, []);
console.log(result);

How to group and merge array entries and to sum-up values on multiple common (but not all) keys?

Just test both properties in the find() callback, and add both to the new object when pushing into acc.

const arr = [
{'ID':'1','Parent':'1','Member': '1','Code': '123','Subject': 'Org A','value': 0.3},
{'ID':'2','Parent':'1','Member': '1','Code': '124','Subject': 'Org A','value': 0.25},
{'ID':'3','Parent':'1','Member': '1','Code': '123','Subject': 'Org B','value': 0.45},
{'ID':'4','Parent':'1','Member': '2','Code': '125','Subject': 'Org A','value': 0.8},
{'ID':'5','Parent':'1','Member': '2','Code': '211','Subject': 'Org C','value': 0.3},
{'ID':'6','Parent':'1','Member': '3','Code': '221','Subject': 'Org B','value': 0.3},
{'ID':'7','Parent':'1','Member': '3','Code': '221','Subject': 'Org C','value': 0.25},
{'ID':'8','Parent':'1','Member': '3','Code': '234','Subject': 'Org A','value': 0.45},
{'ID':'9','Parent':'1','Member': '4','Code': '123','Subject': 'Org A','value': 0.8},
{'ID':'10','Parent':'2','Member': '5','Code': '123','Subject': 'Org D','value': 0.3},
{'ID':'11','Parent':'2','Member': '5','Code': '123','Subject': 'Org E','value': 0.3},
{'ID':'12','Parent':'2','Member': '6','Code': '125','Subject': 'Org E','value': 0.25},
{'ID':'13','Parent':'2','Member': '6','Code': '211','Subject': 'Org F','value': 0.45},
{'ID':'14','Parent':'2','Member': '6','Code': '221','Subject': 'Org F','value': 0.8},
{'ID':'15','Parent':'2','Member': '6','Code': '123','Subject': 'Org G','value': 0.3},
{'ID':'16','Parent':'3','Member': '7','Code': '124','Subject': 'Org H','value': 0.3},
{'ID':'17','Parent':'3','Member': '8','Code': '124','Subject': 'Org H','value': 0.25},
{'ID':'18','Parent':'3','Member': '9','Code': '123','Subject': 'Org I','value': 0.45},
{'ID':'19','Parent':'3','Member': '10','Code': '123','Subject': 'Org J','value': 0.8},
{'ID':'20','Parent':'3','Member': '10','Code': '211','Subject': 'Org I','value': 0.3},
{'ID':'21','Parent':'4','Member': '11','Code': '221','Subject': 'Org K','value': 0.3},
{'ID':'22','Parent':'4','Member': '11','Code': '234','Subject': 'Org K','value': 0.25},
{'ID':'23','Parent':'4','Member': '12','Code': '234','Subject': 'Org K','value': 0.45},
{'ID':'24','Parent':'4','Member': '12','Code': '123','Subject': 'Org L','value': 0.8},
{'ID':'25','Parent':'4','Member': '13','Code': '211','Subject': 'Org M','value': 0.3}
];

const summed = arr.reduce((acc, cur) => {
const item = acc.length > 0 && acc.find(({
Code, Parent
}) => Code === cur.Code && Parent == cur.Parent)
if (item) {
item.value += cur.value
} else acc.push({
Code: cur.Code,
Parent: cur.Parent,
value: cur.value
});
return acc
}, [])
console.log(arr); // not modified
console.log(summed)

GroupBy array of objects to new array and sum value

Looking at your initial array and the output you wanted to get, below are the examples that result in exactly the same structure as per your question - an array of arrays of objects


One way with find & for of loop:

let arr = [
{
"year": "202003",
"cost": 11194.55,
"type": "A"
},
{
"year": "202003",
"cost": 60.2,
"type": "B"
},
{
"year": "202003",
"cost": 747.12,
"type": "C"
},
{
"year": "202003",
"cost": 747.12,
"type": "D"
},
{
"year": "202004",
"cost": 747.12,
"type": "D"
},
{
"year": "202003",
"cost": 4674.59,
"type": "D"
}
]

let sortedArray = []
for (let [index, el] of arr.entries()) {
if(sortedArray.find(elInner => (elInner[0].type === el.type && elInner[0].year !== el.year))) {
sortedArray.find(elInner => elInner[0].type === el.type).push(arr[index])
}else if (sortedArray.find(elInner => (elInner[0].type === el.type && elInner[0].year == el.year))) {
sortedArray.find(elInner => (elInner[0].type === el.type && elInner[0].year == el.year))[0].cost += arr[index].cost
}else {
sortedArray.push([el])
}
}
console.log(sortedArray)

how to group by and total sum array of object in javascript?

You could try something like this

const output = Object.entries(groupByMonth).map(([time, datapoints]) => {
const codes = {}
const allTasks = datapoints.flatMap(point => point.task)
for (const { code, value } of allTasks) {
codes[code] = (codes[code] || 0) + value
}
return {
time,
tasks: Object.entries(codes).map(([code, value]) => ({ code, value }))
}
}

Though one downside is that the time complexity isn't perfect because of the structure of the data



Related Topics



Leave a reply



Submit