Home > Net >  Getting total from 2 objects pushing to new array
Getting total from 2 objects pushing to new array

Time:11-08

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);
}, []);
  • Related