Reputation: 534
I have an Array of Objects where I'm trying to combine a couple of the properties and then return a new Array of Objects. Below is an example of the structure of the original Array of Objects:
[
{
"memID": "180",
"memType": "Movie",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [
{
"poster": "https://image.tmdb.org/t/p/original//7BuH8itoSrLExs2YZSsM01Qk2no.jpg"
}
],
"tvshow": [],
"game": []
},
{
"memID": "65",
"memType": "Game",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [],
"tvshow": [],
"game": [
{
"boxArt": "https://images.igdb.com/igdb/image/upload/t_1080p/co1hvj.jpg"
}
]
},
{
"memID": "178",
"memType": "Movie",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [
{
"poster": "https://image.tmdb.org/t/p/original//5xcXvTErivIgRchsaw9qaT3NflE.jpg"
}
],
"tvshow": [],
"game": []
},
]
What I would like to do is to return a new Array of Objects that groups the data by monthYear
by combining both the month
and year
properties, for example:
[
{
"monthYear": {
"5-1980": {
{
"memID": "180",
"memType": "Movie",
"favourite": null,
"public": null,
"music": [],
"movie": [
{
"poster": "https://image.tmdb.org/t/p/original//7BuH8itoSrLExs2YZSsM01Qk2no.jpg"
}
],
"tvshow": [],
"game": []
},
{
"memID": "65",
"memType": "Game",
"favourite": null,
"public": null,
"music": [],
"movie": [],
"tvshow": [],
"game": [
{
"boxArt": "https://images.igdb.com/igdb/image/upload/t_1080p/co1hvj.jpg"
}
]
},
{
"memID": "178",
"memType": "Movie",
"favourite": null,
"public": null,
"music": [],
"movie": [
{
"poster": "https://image.tmdb.org/t/p/original//5xcXvTErivIgRchsaw9qaT3NflE.jpg"
}
],
"tvshow": [],
"game": []
},
}
}
}
]
I've been trying to flatten the Array and then restructure it but I haven't been able to work out the best approach. I have tried .flat()
, .flatMap()
and a few other methods but haven't had any success.
Upvotes: 0
Views: 54
Reputation: 5853
Use Array.prototype.reduce
to group by your custom key, here's a sample
const data = [{
"memID": "180",
"memType": "Movie",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [{
"poster": "https://image.tmdb.org/t/p/original//7BuH8itoSrLExs2YZSsM01Qk2no.jpg"
}],
"tvshow": [],
"game": []
},
{
"memID": "65",
"memType": "Game",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [],
"tvshow": [],
"game": [{
"boxArt": "https://images.igdb.com/igdb/image/upload/t_1080p/co1hvj.jpg"
}]
},
{
"memID": "178",
"memType": "Movie",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [{
"poster": "https://image.tmdb.org/t/p/original//5xcXvTErivIgRchsaw9qaT3NflE.jpg"
}],
"tvshow": [],
"game": []
},
];
const groupedData = data.reduce((acc, curr) => {
const { month, year } = curr.date;
const k = `${month}-${year}`;
acc[k] = (acc[k] || []).concat(curr);
return acc;
}, Object.create(null));
const results = [{
monthYear: groupedData
}];
console.log(results);
Upvotes: 0
Reputation: 446
I recommend to use lodash/groupBy for this.
const formatted = _.groupBy(data, item => `${item.date.month}-${item.date.year}`);
The function will create the following structure. It's a little bit different, but it groups the items according to month and year
{
"5-1980": [
{
"memID": "180",
"memType": "Movie",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [
{
"poster": "https://image.tmdb.org/t/p/original//7BuH8itoSrLExs2YZSsM01Qk2no.jpg"
}
],
"tvshow": [],
"game": []
},
{
"memID": "65",
"memType": "Game",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [],
"tvshow": [],
"game": [
{
"boxArt": "https://images.igdb.com/igdb/image/upload/t_1080p/co1hvj.jpg"
}
]
},
{
"memID": "178",
"memType": "Movie",
"date": {
"month": 5,
"year": 1980
},
"favourite": null,
"public": null,
"music": [],
"movie": [
{
"poster": "https://image.tmdb.org/t/p/original//5xcXvTErivIgRchsaw9qaT3NflE.jpg"
}
],
"tvshow": [],
"game": []
}
]
}
Upvotes: 2
Reputation: 1564
This should do the job:
inputData.reduce((acc, item) => {
const key = `${item.date.month}-${item.date.year}`;
const { date, ...realData } = item;
acc[key] = [...acc[key] || [], realData];
return acc;
}, {})
Explanation about the code.
const key = `${item.date.month}-${item.date.year}`
- this part creates the key of the item. In your case it's a composition of month-year.
const { date, ...realData } = item
- here we remove the date object from the whole, as you don't need it anymore (as per your desired output)
...acc[key] || []
- if this is the first object in the loop with that key, acc[key]
would be null, so we initialize with an empty array. If that's not the first key, then acc[key]
will already be an array. We then add the newly created object to that array.
Hope this is what you are after.
Upvotes: 0