Search code examples
javascriptnode.jslodash

How to map and group array of objects


I'm building an application with Node.js, Express, Postgres and Sequelize.

I get a response that looks like this:

[
    {
        "id": 101,
        "type": 0,
        "bookings": [
            {
                "date": "2019-04-15T02:00:00.000Z"
            }
        ]
    },
    {
        "id": 102,
        "type": 4,
        "bookings": [
            {
                "date": "2019-04-17T02:00:00.000Z"
            }
        ]
    },
    {
        "id": 103,
        "type": 0,
        "bookings": [
            {
                "date": "2019-04-15T02:00:00.000Z"
            }
        ]
    },
    {
        "id": 104,
        "type": 0,
        "bookings": [
            {
                "date": "2019-04-17T02:00:00.000Z"
            }
        ]
    }
]

I want to group all the events that happen on the same date.

I tried

_.forEach(response, function(value) {
    _.groupBy(value, value.bookings[0].date)
})

but it doesn't work.

How can I map and group an array?

Eventually I want to have an object (or array) that looks something like this:

{
    2019-04-15: [
        { id: 101, type: 0 }, { id: 103, type: 0}
    ],
    2019-04-17: [
        { id: 102, type: 4 }, { id: 104, type: 0}
    ]
}

Solution

  • You can use reduce

    let data = [{"id": 101,"type": 0,"bookings": [{"date": "2019-04-15T02:00:00.000Z"}]},{"id": 102,"type": 4,"bookings": [{"date": "2019-04-17T02:00:00.000Z"}]},{"id": 103,"type": 0,"bookings": [{"date": "2019-04-15T02:00:00.000Z"}]},{"id": 104,"type": 0,"bookings": [{"date": "2019-04-17T02:00:00.000Z"}]}]
    
    let op = data.reduce((op,{bookings,...rest}) => {
      let key = bookings[0].date.split('T',1)[0]
      op[key] = op[key] || []
      op[key].push(rest)
      return op
    },{})
    
    console.log(op)