Reputation: 2594
My goal is from an array object like this:
const data = [
{
code: 'prod1',
quantity: 13,
pricePerItem: 10,
totalCost: 130
},
{
code: 'prod1',
quantity: 7,
pricePerItem: 11,
totalCost: 77
},
{
code: 'prod2',
quantity: 10,
pricePerItem: 9,
totalCost: 90
},
{
code: 'prod2',
quantity: 9,
pricePerItem: 10,
totalCost: 90
},
];
build an object with code as key an object with aggregation data like:
{
prod1:{
quantity: 20,
total: 207
},
prod2:{
quantity: 19,
total:180
}
}
Without the object keys is quite easy
data.reduce(
(acc, current) => {
return {
total: acc.total + current.totalCost,
quantity: acc.quantity + current.quantity
};
},
{ total: 0, quantity: 0 }
);
but with the object keys I'm stuck Could you help me, please?
Upvotes: 1
Views: 209
Reputation: 13243
const data = [
{
code: 'prod1',
quantity: 13,
pricePerItem: 10,
totalCost: 130
},
{
code: 'prod1',
quantity: 7,
pricePerItem: 11,
totalCost: 77
},
{
code: 'prod2',
quantity: 10,
pricePerItem: 9,
totalCost: 90
},
{
code: 'prod2',
quantity: 9,
pricePerItem: 10,
totalCost: 90
},
];
let output = data.reduce((acc, val) => ({
...acc, // Spread out the accumulator
[val.code]: {
// If it doesn't exist yet, make it 0, and add the current val's property
quantity: ((acc[val.code] && acc[val.code].quantity ) || 0) + val.quantity,
totalCost: ((acc[val.code] && acc[val.code].totalCost) || 0) + val.totalCost
}
}), {});
// Override console.log to make it look the way I want it to look
// This is just aesthetics
console.log = (...args) => {
for (let arg of args) {
const pre = document.createElement("pre");
pre.innerText = JSON.stringify(arg, null, 2);
document.querySelector("body").appendChild(pre);
}
};
// --------------------------
// --------------------------
console.log(output)
html,
body {
background: whitesmoke;
}
pre {
color: black;
background: white;
padding: 1rem;
border: 2px solid black;
border-radius: 1rem;
}
Upvotes: 0
Reputation: 3683
const data = [
{
code: "prod1",
quantity: 13,
pricePerItem: 10,
totalCost: 130
},
{
code: "prod1",
quantity: 7,
pricePerItem: 11,
totalCost: 77
},
{
code: "prod2",
quantity: 10,
pricePerItem: 9,
totalCost: 90
},
{
code: "prod2",
quantity: 9,
pricePerItem: 10,
totalCost: 90
}
];
console.log(
data.reduce((acc, current) => {
if (!acc[current.code]) {
acc[current.code] = { quantity: 0, total: 0 };
}
return {
...acc,
[current.code]: {
quantity: acc[current.code].quantity + current.quantity,
total: acc[current.code].total + current.totalCost
}
};
}, {})
);
Upvotes: 2
Reputation: 1509
const data = [
{
code: 'prod1',
quantity: 13,
pricePerItem: 10,
totalCost: 130
},
{
code: 'prod1',
quantity: 7,
pricePerItem: 11,
totalCost: 77
},
{
code: 'prod2',
quantity: 10,
pricePerItem: 9,
totalCost: 90
},
{
code: 'prod2',
quantity: 9,
pricePerItem: 10,
totalCost: 90
},
];
var result =
data.reduce(
(acc, current) => {
acc[current.code] = acc[current.code] || { quantity: 0, total: 0 };
acc[current.code] = {
total: acc[current.code].total + current.totalCost,
quantity: acc[current.code].quantity + current.quantity,
};
return acc;
},
{}
);
console.log(result);
Upvotes: 1
Reputation: 5054
You can use reduce to do the following,
const res = data.reduce((prev, curr) => {
if(prev.hasOwnProperty(curr.code)) {
prev[curr.code] = {total: prev[curr.code].total + curr.totalCost, quantity: prev[curr.code].quantity + curr.quantity };
return prev;
} else {
prev[curr.code] = {total: curr.totalCost, quantity: curr.quantity };
return prev;
}
}, {});
console.log(res);
Upvotes: 2