I have an array with following structure:
BasketDish
[
{
id: string;
quantity: number;
Dish: AsyncItem<Dish | undefined>;
basketID: string;
createdAt?: string | null;
updatedAt?: string | null;
basketDishDishId?: string | null;
}
]
Dish
[
{
id: string;
name: string;
price: number;
},
{
id: string;
name: string;
price: number;
}
]
I need to group the array by Dish.id and then create an array which accumulates the quantity and total price
From:
[
{
id: 1,
name: BBQ Burger,
price: 17
},
{
id: 2,
name: CheeseBurger,
price: 15
},
{
id: 2,
name: CheeseBurger,
price: 15
},
]
To expected result:
[
{
id: 1,
name: BBQ Burger,
price: 17,
total: 17,
quantity: 1
},
{
id: 2,
name: CheeseBurger,
price: 15,
total: 30,
quantity: 2
},
]
I tried a lot with groupBy and merge, but couldn't figure it out
Thanks @BioStunt
Just needed to update your solution instead of group by id i had to group by Dish.id
/**
* Merge Dishes with same id
*/
const groupedItems = chain(basketDishes)
/** group items by key "id" */
.groupBy(a => a.Dish?.id)
/** convert grouped items */
.map((items, id) => ({
id: id,
dishId: items[0]?.Dish?.id,
name: items[0].Dish?.name,
quantity: items.length,
total: items.reduce((acc, item) => acc + item.Dish?.price!, 0),
}))
/** get result of chain */
.value();
If I correctly understood your question, you should use chain + groupBy from lodash
.
In your case you have base item array:
const basketDish = [
{ id: 1, name: 'BBQ Burger', price: 17 },
{ id: 2, name: 'CheeseBurger', price: 15 },
{ id: 2, name: 'CheeseBurger', price: 15 },
];
To merge this data use this:
const groupedItems = chain(basketDish)
/** group items by key "id" */
.groupBy('id')
/** convert grouped items */
.map((items, id) => ({
id: Number(id),
name: items[0].name,
quantity: items.length,
total: items.reduce((acc, item) => acc + item.price, 0)
}))
/** get result of chain */
.value();
Below is the console output:
groupedItems.forEach((item) =>
console.log(`${item.quantity} * ${item.name} | ${item.total}`)
);