0

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.

3 Answers 3

2

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": []
    }
  ]
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for taking the time to look at this. I haven't used lodash before but looks very useful! I'm just testing this out - do you know if there's any way to also rank the order by year? i.e. 5-1980, 6-1980....1-1981, 2-1981...1-1982, 2-1982...
For that, you could use Array.prototype.sort. At first, I would sort the items and then group them with groupBy(). If sort looks a little bit complicated, lodash has another good method: orderBy
Yes, was just looking at orderBy - seems to have done the trick. Thanks so much for your help!
0

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.

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.