Reputation: 66
I have an array that looks like this
myArray = [
Object {
"_id": "0c35e243",
"createdDate": "2021-05-19T08:58:14.497Z",
"description": "desc text",
},
Object {
"_id": "08e05fcb",
"createdDate": "2022-07-19T08:42:34.702Z",
"desc": "desc text2",
},
Object {
"_id": "6a33dca3",
"createdDate": "2021-07-19T08:35:53.199Z",
"desc": "desc text3",
},
Object {
"_id": "58ea808d",
"createdDate": "2022-08-19T08:13:35.516Z",
"desc": "desc text4",
},
Object {
"_id": "a95b706c",
"createdDate": "2022-08-19T04:12:44.941Z",
"desc": "desc text5",
},
]
I want to sort it by year and month so it would look like this
newArray = [
"2022" : [
"7" : [
Object {
"_id": "08e05fcb",
"createdDate": "2022-07-19T08:42:34.702Z",
"desc": "desc text2",
}
],
"8" : [
Object {
"_id": "58ea808d",
"createdDate": "2022-08-19T08:13:35.516Z",
"desc": "desc text4",
},
Object {
"_id": "a95b706c",
"createdDate": "2022-08-19T04:12:44.941Z",
"desc": "desc text5",
},
]
],
"2021" : [
"5" : [
Object {
"_id": "0c35e243",
"createdDate": "2021-05-19T08:58:14.497Z",
"description": "desc text",
}
],
"7" : [
Object {
"_id": "6a33dca3",
"createdDate": "2021-07-19T08:35:53.199Z",
"desc": "desc text3",
}
]
]
]
i've been trying to use lodash groupBy
const groupByMonth = groupBy(myArray, ({createdDate})=> new Date(createdDate).getMonth());
with result like this
Object {
"5": Array [
Object {
"_id": "0c35e243",
"createdDate": "2021-05-19T08:58:14.497Z",
"description": "desc text",
},
],
"7": Array [
Object {
"_id": "08e05fcb",
"createdDate": "2022-07-19T08:42:34.702Z",
"desc": "desc text2",
},
Object {
"_id": "6a33dca3",
"createdDate": "2021-07-19T08:35:53.199Z",
"desc": "desc text3",
},
],
"8": Array [
Object {
"_id": "58ea808d",
"createdDate": "2022-08-19T08:13:35.516Z",
"description": "desc text4",
},
Object {
"_id": "a95b706c",
"createdDate": "2022-08-19T04:12:44.941Z",
"desc": "desc text5",
},
],
}
Now what should i do next? I've tried
const groupByYear = groupBy(groupByMonth, ({_createdDate}) => new Date(_createdDate).getYear());
but i think it's not the solution since it return NaN
as the year and it wont group the month like what I expected too
It's okay if the solution is not using lodash as long as the result is look like the expected result also if its possible I would like to use the month name so its not 5,7,8 but May, July, August etc.
Upvotes: 0
Views: 852
Reputation: 181
Here is my solution without lodash, and I also convert month of the year from number to short name. Hope can help you
const myArray = [
{
_id: '0c35e243',
createdDate: '2021-05-19T08:58:14.497Z',
description: 'desc text'
},
{
_id: '08e05fcb',
createdDate: '2022-07-19T08:42:34.702Z',
desc: 'desc text2'
},
{
_id: '6a33dca3',
createdDate: '2021-07-19T08:35:53.199Z',
desc: 'desc text3'
},
{
_id: '58ea808d',
createdDate: '2022-08-19T08:13:35.516Z',
desc: 'desc text4'
},
{
_id: 'a95b706c',
createdDate: '2022-08-19T04:12:44.941Z',
desc: 'desc text5'
}
];
const output = myArray.reduce((acc, cur) => {
const createdDate = new Date(cur.createdDate)
const year = createdDate.getFullYear()
const monthShortName = createdDate.toLocaleString('en-us', { month: 'short' })
// Get year object corresponding to current item from acc (or insert if not present)
const groupByYear = acc[year] = acc[year] || {};
//Get month array corresponding to current item from groupByYear object (or insert if not present)
const groupByMonth = groupByYear[monthShortName] = groupByYear[monthShortName] || [];
// Add current item to current groupByMonth array
groupByMonth.push(cur);
return acc
}, {});
console.log(output);
Upvotes: 0
Reputation: 56410
This is my version.
const myArray = [
{
_id: '0c35e243',
createdDate: '2021-05-19T08:58:14.497Z',
description: 'desc text',
},
{
_id: '08e05fcb',
createdDate: '2022-07-19T08:42:34.702Z',
desc: 'desc text2',
},
{
_id: '6a33dca3',
createdDate: '2021-07-19T08:35:53.199Z',
desc: 'desc text3',
},
{
_id: '58ea808d',
createdDate: '2022-08-19T08:13:35.516Z',
desc: 'desc text4',
},
{
_id: 'a95b706c',
createdDate: '2022-08-19T04:12:44.941Z',
desc: 'desc text5',
},
];
function transform(data, keyName) {
const output = [];
_.forIn(data, (value, key) => {
value[keyName] = key;
output.push(value);
});
return output;
}
const groupedByYear = _.groupBy(myArray, (item) =>
moment(item.createdDate).year()
);
const groupedByYearArray = transform(groupedByYear, 'year').sort();
console.log(groupedByYearArray);
const output = groupedByYearArray.map((item) => {
const groupedByMonth = _.groupBy(myArray, (item) =>
moment(item.createdDate).month()
);
return transform(groupedByMonth, 'month').sort();
});
console.log(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.2.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
Upvotes: 0
Reputation: 150
let myArray = [
{
"_id": "0c35e243",
"createdDate": "2021-05-19T08:58:14.497Z",
"description": "desc text",
},
{
"_id": "08e05fcb",
"createdDate": "2022-07-19T08:42:34.702Z",
"desc": "desc text2",
},
{
"_id": "6a33dca3",
"createdDate": "2021-07-19T08:35:53.199Z",
"desc": "desc text3",
},
{
"_id": "58ea808d",
"createdDate": "2022-08-19T08:13:35.516Z",
"desc": "desc text4",
},
{
"_id": "a95b706c",
"createdDate": "2022-08-19T04:12:44.941Z",
"desc": "desc text5",
},
]
This did the trick for me. I used a package called moment to split the year and month.
const groupByYear = (array) => {
let group = {}
array.forEach((elem)=>{
let year = moment(elem.createdDate).format('YYYY')
if(!group[year]){
group[year] = {}
let month = moment(elem.createdDate).format('MM')
if(!group[year][month]){
group[year][month] = [elem]
}else{
group[year][month].push(elem)
}
}else{
let month = moment(elem.createdDate).format('MM')
if(!group[year][month]){
group[year][month] = [elem]
}else{
group[year][month].push(elem)
}
}
})
return group
}
Upvotes: 0
Reputation: 652
let myArray = [
{"_id": "0c35e243", "createdDate": "2021-05-19T08:58:14.497Z", "description": "desc text"},
{"_id": "08e05fcb", "createdDate": "2022-07-19T08:42:34.702Z", "desc": "desc text2"},
{"_id": "6a33dca3", "createdDate": "2021-07-19T08:35:53.199Z", "desc": "desc text3"},
{"_id": "58ea808d", "createdDate": "2022-08-19T08:13:35.516Z", "desc": "desc text4"},
{"_id": "a95b706c", "createdDate": "2022-08-19T04:12:44.941Z", "desc": "desc text5"},
];
let output = {};
myArray.forEach(elem => {
let date = new Date(elem.createdDate);
let year = date.getFullYear();
let month = date.getMonth() + 1;
if(output[year]) {
if(output[year][month]) {
output[year][month].push(elem);
} else {
output[year][month] = [elem];
}
} else {
output[year] = {
[month]: [elem]
}
}
});
console.log(output);
Upvotes: 0
Reputation: 1869
let out = {} ;
myArray.forEach( e => {
const [ year, month ] = e.createdDate.split("-") ;
out[ year ] ??= {} ;
out[ year ][ month ] ??= [] ;
out[ year ][ month ].push( e ) ;
} ) ;
=>
{
'2021': {
'05': [
{
_id: '0c35e243',
createdDate: '2021-05-19T08:58:14.497Z',
description: 'desc text'
}
],
'07': [
{
_id: '6a33dca3',
createdDate: '2021-07-19T08:35:53.199Z',
desc: 'desc text3'
}
]
},
'2022': {
'07': [
{
_id: '08e05fcb',
createdDate: '2022-07-19T08:42:34.702Z',
desc: 'desc text2'
}
],
'08': [
{
_id: '58ea808d',
createdDate: '2022-08-19T08:13:35.516Z',
desc: 'desc text4'
},
{
_id: 'a95b706c',
createdDate: '2022-08-19T04:12:44.941Z',
desc: 'desc text5'
}
]
}
}
Upvotes: 4
Reputation: 2930
myArray = [
{
"_id": "0c35e243",
"createdDate": "2021-05-19T08:58:14.497Z",
"description": "desc text",
},
{
"_id": "08e05fcb",
"createdDate": "2022-07-19T08:42:34.702Z",
"desc": "desc text2",
},
{
"_id": "6a33dca3",
"createdDate": "2021-07-19T08:35:53.199Z",
"desc": "desc text3",
},
{
"_id": "58ea808d",
"createdDate": "2022-08-19T08:13:35.516Z",
"desc": "desc text4",
},
{
"_id": "a95b706c",
"createdDate": "2022-08-19T04:12:44.941Z",
"desc": "desc text5",
},
]
const newArray = _.groupBy(myArray, ({ createdDate }) => (new Date(createdDate)).toLocaleString('en-us',{month:'short', year:'numeric'}))
console.log(newArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
I don't know why you append "_" to "createdDate" tho. It should work this way.
Upvotes: 1