I'm attempting to have get a data output for the amount of orders per shoe color. Each shoe sold has only 2 sizes that can be sold. I would like to get the total amount of each size sold into 1 object per order date.
I've attempted to push into a new array that gets the total of sizes per order Date into a new object
I've attempted to do this my looping through and applying a filter but my return is breaking due to orders being undefined. I believe the issue is due to my additional filters with
let sizeNine = sales.filter(sale => sale.size == "9")[0]
let sizeEleven = sales.filter(sale => sale.size == "11")[0]
const data = [
{
color: 'red',
order_date: '2022-11-01',
size: '9',
orders: 4
},
{
color: 'red',
order_date: '2022-11-01',
size: '11',
orders: 8
},
{
color: 'yellow',
order_date: '2022-11-04',
size: '9',
orders: 1
},
{
color: 'yellow',
order_date: '2022-11-04',
size: '11',
orders: 4
},
]
let combinedSales = []
for (let i = 0; i < data.length; i ) {
let currentSale = data[i]
let sales = data.filter(sale => sale.size == currentSale.size && sale.order_date == currentSale.order_date)
let sizeNine = sales.filter(sale => sale.size == "9")[0]
let sizeEleven = sales.filter(sale => sale.size == "11")[0]
combinedSales.push({
orderDate: currentSale.order_date,
sizeNineTotal: sizeNine.orders,
sizeElevenTotal: sizeEleven.orders,
totalOrders: sizeNine.orders sizeEleven.orders
})
}
console.log(combinedSales)
I am having trouble thinking of the correct logic to execute this, how can I achieve this output?
const data = [
{
orderDate: '2022-11-01',
sizeNineTotal: 9,
sizeElevenTotal: 8,
totalOrder: 17
},
{
orderDate: '2022-11-04',
sizeNineTotal: 1,
sizeElevenTotal: 4,
totalOrder: 5
},
]
CodePudding user response:
You can use reduce()
to do it
a. Traditional way:
let result = data.reduce((a,c) =>{
let obj = a.find(i => i.orderDate == c.order_date)
let key = c.size == '9' ? 'sizeNineTotal':'sizeElevenTotal'
if(obj){
obj.totalOrder = c.orders
obj[key] = c.orders
}else{
obj = {'orderDate':c.order_date,'sizeNineTotal':0,'sizeElevenTotal':0,'totalOrder':c.orders}
obj[key] = c.orders
a.push(obj)
}
return a
},[])
console.log(result)
b. Use one-liner combined with Object.values()
let result = Object.values(data.reduce((a,{order_date,size,orders}) =>
({...a, [order_date]:
{'orderDate':order_date,
'sizeNineTotal':(size == 9 ? orders : 0) (a[order_date]?.sizeNineTotal??0),
'sizeElevenTotal':(size == 11 ? orders : 0) (a[order_date]?.sizeElevenTotal??0),
'totalOrders': orders (a[order_date]?.totalOrders??0)}
}), {}))
console.log(result)
const data = [
{
color: 'red',
order_date: '2022-11-01',
size: '9',
orders: 4
},
{
color: 'red',
order_date: '2022-11-01',
size: '11',
orders: 8
},
{
color: 'yellow',
order_date: '2022-11-04',
size: '9',
orders: 1
},
{
color: 'yellow',
order_date: '2022-11-04',
size: '11',
orders: 4
}
]
let result = Object.values(data.reduce((a,{order_date,size,orders}) =>
({...a, [order_date]:
{'orderDate':order_date,
'sizeNineTotal':(size == 9 ? orders : 0) (a[order_date]?.sizeNineTotal??0),
'sizeElevenTotal':(size == 11 ? orders : 0) (a[order_date]?.sizeElevenTotal??0),
'totalOrders': orders (a[order_date]?.totalOrders??0)}
}), {}))
console.log(result)
CodePudding user response:
You're right in thinking you should separate concerns (sizeNine, sizeEleven). Sometimes it can help to start with very simple bits of information and verify them
let sizeList = [...new Set(data.map(i => i.size))];
// OK, now we have a list of sizes ["9", "11"]
let dateList = [...new Set(data.map(i => i.order_date))];
// Now we have a list of dates
let combinedSales = dateList.reduce((carry, date) =>
{
let salesOnDay = data.filter(i => i.order_date === date);
// Now we have a list of orders for this day
let sizeNineTotal = salesOnDay.filter(i => i.size === '9').map(i => i.orders).reduce((carry, item) => carry item, 0);
let sizeElevenTotal = salesOnDay.filter(i => i.size === '11').map(i => i.orders).reduce((carry, item) => carry item, 0);
// Producing our totals is a simple matter of filtering the per-day array by size, mapping to the orders property and reducing it to a total value
carry.push(
{
orderDate: date,
sizeNineTotal: sizeNineTotal,
sizeElevenTotal: sizeElevenTotal,
totalOrder: sizeNineTotal sizeElevenTotal
});
return(carry);
}, []);