I have an array of objects and i need to classify each object by name and then get the addition of some properties.
To be more specific, I have a cart with some orders and i need to breakdown by product name so i can calculate how many items of that product were bought.
const orders = [
{
name: 'Isaac',
products: [
{
name: 'Apple',
unit: 'x6 und',
qty: 1
},
{
name: 'Lemon',
unit: '500gr',
qty: 2
},
{
name: 'Coconut',
unit: 'x3 und',
qty: 1
},
{
name: 'Orange',
unit: 'kg',
qty: 1
},
]
},
{
name: 'Andrea',
products: [
{
name: 'Apple',
unit: 'x6 und',
qty: 2
},
{
name: 'Lemon',
unit: '500gr',
qty: 3
},
{
name: 'Coconut',
unit: 'x3 und',
qty: 2
},
{
name: 'Garlic',
unit: '250 gr',
qty: 2
},
]
},
{
name: 'George',
products: [
{
name: 'Apple',
unit: 'x6 und',
qty: 3
},
{
name: 'Lemon',
unit: '500gr',
qty: 4
},
{
name: 'Coconut',
unit: 'x3 und',
qty: 3
},
{
name: 'Garlic',
unit: '250 gr',
qty: 1
},
]
}
]
That is the dummy data,
I mapped the orders array and then mapped the products array, then i used .flat() method to get another array of objects but simplified.
Now I am stuck.
const resume = orders.map(order => {
return order.products.map(prods => {
return prods
})
})
console.log(resume.flat());
This is the result:
[
{ name: 'Apple', unit: 'x6 und', qty: 1 },
{ name: 'Lemon', unit: '500gr', qty: 2 },
{ name: 'Coconut', unit: 'x3 und', qty: 1 },
{ name: 'Orange', unit: 'kg', qty: 1 },
{ name: 'Apple', unit: 'x12 und', qty: 2 },
{ name: 'Apple', unit: 'x6 und', qty: 2 },
{ name: 'Lemon', unit: '500gr', qty: 3 },
{ name: 'Coconut', unit: 'x3 und', qty: 2 },
{ name: 'Garlic', unit: '250 gr', qty: 2 },
{ name: 'Apple', unit: 'x6 und', qty: 3 },
{ name: 'Lemon', unit: '500gr', qty: 4 },
{ name: 'Coconut', unit: 'x3 und', qty: 3 },
{ name: 'Garlic', unit: '250 gr', qty: 1 }
]
At this point, i need to know how many apples, Coconut, Garlic were sold.
Example: name: ‘Apple’, unit: ‘X6 und’, qty: 6 name: ‘Apple’, unit: ‘X12 und’, qty: 1 name: ‘Lemon’, unit: ‘500gr’, qty: 9 an so on…
Any clue? I am completely lost 🙁
Advertisement
Answer
Probably not as elegant as reduce
, but kind of fun, is the following:
Starting with your original orders
(no need for the intermediate step, unless you want it), initiate an empty array, like ordersArray = []
, and run the following:
orders.forEach((order) => {
order.products.forEach((product) => {
const index = ordersArray.findIndex((prod) => prod.name === product.name);
index === -1 ? ordersArray.push(product) : ordersArray[index].qty += product.qty
});
});
Your result is:
ordersArray = [
{ name: 'Apple', unit: 'x6 und', qty: 6 },
{ name: 'Lemon', unit: '500gr', qty: 9 },
{ name: 'Coconut', unit: 'x3 und', qty: 6 },
{ name: 'Orange', unit: 'kg', qty: 1 },
{ name: 'Garlic', unit: '250 gr', qty: 3 },
]
This looks right (I’m not sure where the { name: 'Apple', unit: 'x12 und', qty: 2 }
object came from for your intermediate step 🙂 ).
Lately, I’ve been storing this kind of information in an object (see here). It would be very similar, with only slight differences: Start with the same orders
(obviously), and then define an empty object ordersObject = {}
.
orders.forEach((order) => {
order.products.forEach((product) => {
ordersObject[product.name] = { unit: product.unit, qty: (ordersObject[product.name]?.qty || 0) + product.qty }
});
});
The result is similar, but easier to update, retrieve data, etc.
ordersObject = {
Apple: { unit: 'x6 und', qty: 6 },
Lemon: { unit: '500gr', qty: 9 },
Coconut: { unit: 'x3 und', qty: 6 },
Orange: { unit: 'kg', qty: 1 },
Garlic: { unit: '250 gr', qty: 3 }
}