Filter number of orders in each month from given array data

Viewed 61

I have the following data object. Each record contains order value and month of order. My objective here is to count how many orders per month have been ordered.

const data = [{
  order: "a",
  date: "Jan"
}, {
  order: "b",
  date: "Jan"
}, {
  order: "c",
  date: "Feb"
}]

So in the above code in Jan there are two orders, one orders in Feb and no orders for the rest of the months. So for the months which have no orders will have 0 value.

The expected output will be (array format)

orders = [{"Jan":2},
          {"Feb":1},
          {"Mar":0},
          {"Apr":0},
          {"Jun":0},
          {"Jul":0},
          {"Aug":0},
          {"Sept":0},
          {"Oct":0},
          {"Nov":0},
          {"Dec":0}]

Here is the CodeSandbox .

3 Answers

You can use a combination of Array.reduce and Array.map to achieve this quite easily, and in a quite readable manner:

const data = [{
  order: "a",
  date: "Jan"
}, {
  order: "b",
  date: "Jan"
}, {
  order: "c",
  date: "Feb"
}]

// A helper array containing all months
const months = ['Jan', 'Feb', 'March'] // ... and so on

// create an object with keys being month name and value being number of orders during that month
const monthsWithOrders = data.reduce((allOrders, currentOrder) => {
  if (allOrders[currentOrder.date]) {
    allOrders[currentOrder.date] += 1
  } else {
    allOrders[currentOrder.date] = 1
  }

  return allOrders
}, {})

// create an array with an oject for each month
const result = months.map(month => {
  return {
    [month]: monthsWithOrders[month] || 0
  }
})

console.log(result)

// results will be:
// [{
//     "Jan": 2
//   },
//   {
//     "Feb": 1
//   },
//   {
//     "March": 0
//   }
// ]

  1. Group by the date
  2. map() over each month, set to the grouped value, or 0 as fallback

const data = [{order: "a", date: "Jan"}, {order: "b", date: "Jan"}, {order: "c", date: "Feb"}];

const grouped = data.reduce((p, c) => {
    p[c.date] = (p[c.date] || 0) + 1;
    return p;
}, {})

const result = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]
  .map(m => ({ [m]: grouped[m] || 0 }));

console.log(result);

Result:

[
  {
    "Jan": 2
  },
  {
    "Feb": 1
  },
  {
    "Mar": 0
  },
  {
    "Apr": 0
  },
  {
    "May": 0
  },
  {
    "Jun": 0
  },
  {
    "Jul": 0
  },
  {
    "Aug": 0
  },
  {
    "Sep": 0
  },
  {
    "Oct": 0
  },
  {
    "Nov": 0
  },
  {
    "Dec": 0
  }
]

forEach and filter is enough for us to make this array object. Also, we can make it with using reduce.

   const data= [{
    order: "a",
    date: "Jan"
  }, {
    order: "b",
    date: "Jan"
  }, {
    order: "c",
    date: "Feb"
  }]
  const weeks = ["Feb", "Jan", "May"]
  const newArray= []
  weeks.forEach((element) => {
    let obj = {}
    const lengtOfData = data.filter(eachData=> element == eachData.date)
    obj[element] = lengtOfData.length
    newArray.push(obj)
  })
Related