2

This is my Input json

"data": [
        {
            "id":3,
            "created_by": 1,
            "created_at": "2022-01-31T07:00:01.880Z",
        },
        {
            "id":2,
            "created_by": 1,
            "created_at": "2022-01-31T07:00:01.880Z",
        },
        {
            "id":1,
            "created_by": 1,
            "created_at": "2022-01-31T07:00:01.880Z",
        }
    ]

I want to sort a resultent json out put with year and month means each year it has to grouped by each month for that i tried the below code it is working fine for year alone and month alone but i am not sure how can i combaine both together i tried calling groupedByYear inside groupedByMonth But it is not givinng me output rather it is throwing Undefined out put the code and the outputs are given below. And the result which i am looking for as well.

    var groupedByYear = _.groupBy(flashMessage,function(item:any) {
        return item.created_at.getFullYear();
    });

    var groupedByMonth = _.groupBy(flashMessage,function(item:any) {
        return item.created_at.getMonth();
    });

Both are returning results correctly. as follows. 1)

 "2021": [
            {
                "created_by": 1,
                "created_at": "2021-01-31T06:54:27.733Z",
            }
        ],
       "2022": [
            {
                "created_by": 1,
                "created_at": "2022-01-31T06:54:27.733Z",
            }
        ],
  1. "0": [
             {
                 "created_by": 1,
                 "created_at": "2021-01-31T06:54:27.733Z",
             }
         ],
        "1": [
             {
                 "created_by": 1,
                 "created_at": "2022-02-31T06:54:27.733Z",
             }
         ],
    

But i want a result somthing like this

   "2021": [
               0:[ {
                    "created_by": 1,
                    "created_at": "2021-01-31T06:54:27.733Z",
                }]
            ],
           "2022": [
               0:[ {
                    "created_by": 1,
                    "created_at": "2022-01-31T06:54:27.733Z",
                }]
               1:[ {
                    "created_by": 1,
                    "created_at": "2022-02-31T06:54:27.733Z",
                }]

            ],

How can I do this? I am using type script with nodejs and my db is postgres. Is there some one who can help me with this?

Julian
  • 4,176
  • 19
  • 40
xxoyx
  • 81
  • 8

2 Answers2

2

You can do it without underscore using a simple reduce

const flashMessages = [
            {
             "created_by": 1,
             "created_at": "2021-01-31T06:54:27.733Z",
             },
           {
             "created_by": 2,
             "created_at": "2021-02-25T06:54:27.733Z",
             },
            {
             "created_by": 3,
             "created_at": "2021-01-31T06:54:27.733Z",
             },
          {
         "created_by": 3,
         "created_at": "2022-02-01T06:54:27.733Z",
         },
         
         ]
         
         const months = [
           'jan',
           'feb',
           'mar',
           'apr',
           'may',
           'jun',
           'jul',
           'sep',
           'oct',
           'nov',
           'dec'
         ]
         
const result = flashMessages.reduce((res, item) => {
   const date = new Date(item.created_at)
   
   const year = date.getFullYear();
   const month = months[date.getMonth()]
   
   const existingYear = res[year] || {}
   res[year] = existingYear
   const updated  = [...(existingYear[month] || []), item]
   
   res[year][month] = updated
   
   return res
}, {});

console.log(result)
R4ncid
  • 6,944
  • 1
  • 4
  • 18
0

You can get the desired result in a clean functional style by adding in _.mapObject as well.

var data = [{
    "id": 3,
    "created_by": 1,
    "created_at": "2022-01-31T07:00:01.880Z",
}, {
    "id": 2,
    "created_by": 1,
    "created_at": "2022-01-31T07:00:01.880Z",
}, {
    "id": 1,
    "created_by": 1,
    "created_at": "2022-01-31T07:00:01.880Z",
}];

var months = 'jan feb mar apr may jun jul aug sep oct nov dec'.split(' ');

function getDate(item) {
    return new Date(item.created_at);
}

function getMonth(item) {
    return months[getDate(item).getMonth()];
}

function getYear(item) {
    return getDate(item).getFullYear();
}

function groupByMonths(items) {
    return _.groupBy(items, getMonth);
}

var byYear = _.groupBy(data, getYear);
var result = _.mapObject(byYear, groupByMonths);

console.log(result);
<script src="https://underscorejs.org/underscore-umd-min.js"></script>

For bonus points, you can use _.partial as well so you don't have to write the groupByMonths function. In that case, the last line turns into this:

var result = _.mapObject(byYear, _.partial(_.groupBy, _, getMonth));
Julian
  • 4,176
  • 19
  • 40