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 } }