Search code examples
javascriptfiltergroup-byrefactoring

Refactoring request: the result array of groupBy function needs to return only the items with non-empty array


const data = [
  {
    date: "2022-11-30T07:33:07.992955008Z",
    reponame: "test-repo",
    category: "veggy",
  },
  {
    date: "2022-11-30T07:33:07.992956372Z",
    reponame: "veggy-repo",
    category: "fruit",
  },
  {
    date: "2022-11-30T07:33:07.992956372Z",
    reponame: "veggy-repo",
    category: "veggy",
  },
  {
    date: "2022-11-30T07:33:07.992956372Z",
    reponame: "vegy-repo",
    category: "vegy",
  },
];

here is my groupByDate function:

const moment = require('moment')

const monthsAcc = [{'January':[]}, {'February':[]}, {'March':[]}, {'April':[]}, {'May':[]}, {'June':[]}, {'July':[]}, {'August':[]}, {'September':[]}, {'October':[]}, {'November':[]}, {'December':[]}]

const groupByDate = (data) => {
  return data.reduce((acc, currentValue) => {
    const month = moment(currentValue["date"]).format('MMMM');
    const monthInAcc = acc.find((item)=>Object.keys(item).includes(month));
    monthInAcc[month].push(currentValue)
  return acc;
  }, monthsAcc);
};

console.log(groupByDate(seb))

My purpose is to make the result include only items with non-empty array as a value (If possible, there is a need to get rid of initial ACC array. other refactoring suggestions are always welcomed)


Solution

  • If you want your final result in the format [{January:[...]},{February:[...]},...] (array of objects where each entry represents a month) and to dynamically create the result.

    You can dynamically initialize and push using the lines

        acc[month] = acc[month] || {[month]:[]}
        acc[month][month].push(currentValue)
    

    also use an object for the accumulator for easy lookup. After doing everything you can call Object.values to get an array of just the values as you need.

    const data = [  {    date: "2022-04-30T07:33:07.992955008Z",    reponame: "test-repo",    category: "veggy",  },  {    date: "2022-06-30T07:33:07.992956372Z",    reponame: "veggy-repo",    category: "fruit",  }, {    date: "2022-11-30T07:33:07.992956372Z",   reponame: "veggy-repo",    category: "veggy",  },  {    date: "2022-11-30T07:33:07.992956372Z",    reponame: "vegy-repo",category: "vegy",  },];
    //edited the month numbers to better visualize the result
    
    const groupByDate = (data) => {
      return Object.values(data.reduce((acc, currentValue) => {
        const month = moment(currentValue["date"]).format('MMMM');
        acc[month] = acc[month] || {[month]:[]}
        acc[month][month].push(currentValue)
        return acc;
      }, {}));
    };
    
    console.log(groupByDate(data))
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>