'Efficient Filtration of nested Object: Lodash or plain JavaScript

I am new to lodash. I have a javascript object as mentioned below. The purpose of this is to explore/learn efficient filter process of objects specially when data is huge and is nested too. I appreciate your guidance in this regard.

JavaScript Object is:

{
 "Bus-1": {
 "Seat1": {
   "Bookings": {
    "21032022": {
      "BookedAt": "21/03/2022 3:43 PM",
      "BookedBy": "Jon Doe"
    },
    "22032022": {
      "BookedAt": "21/03/2022 9:43 PM",
      "BookedBy": "James"
    }
  },
  "Id": 1
},
"Seat2": {
  "Bookings": {
    "20032022": {
      "BookedAt": "21/03/2022 3:43 PM",
      "BookedBy": "Elijah"
    },
    "21032022": {
      "BookedAt": "21/03/2022 3:43 PM",
      "BookedBy": "Scott"
    }
  },
  "Id": 2
},
"Seat3": {
  "Bookings": {
    "22032022": {
      "BookedAt": "22/03/2022 02:41 AM",
      "BookedBy": "Williams"
    }
  },
  "Id": 3
}
 },
 "Bus-2": {
 "Seat1": {
  "Bookings": {
    "22032022": {
      "BookedAt": "22/03/2022 02:39 AM",
      "BookedBy": "Lucas"
    }
  },
  "Id": 1
    }
  }
}

From the above collection, the object hierarchy is as mentioned below in the image.

enter image description here

What I have Tried So Far

 loop...
 Object to array and then array filter function which further leads to filtration again and again
 Object to array and then lodash filter function which also cause nested filtration again and again in this case

What I want to Achieve:

So far what I have identified is looping and filtration slow the process when there is huge data. I am looking for an efficient method which return an object of all Bookings based on dates as mentioned below so that I can further validated if user has booking for same day or not.

    "21032022": {
      "BookedAt": "21/03/2022 3:43 PM",
      "BookedBy": "Jon Doe"
    },
    "22032022": {
      "BookedAt": "21/03/2022 9:43 PM",
      "BookedBy": "James"
    },
    "20032022": {
      "BookedAt": "21/03/2022 3:43 PM",
      "BookedBy": "Elijah"
    },
    "21032022": {
      "BookedAt": "21/03/2022 3:43 PM",
      "BookedBy": "Scott"
    },
    "22032022": {
      "BookedAt": "22/03/2022 02:41 AM",
      "BookedBy": "Williams"
    },
    "22032022": {
      "BookedAt": "22/03/2022 02:39 AM",
      "BookedBy": "Lucas"
    }

Regards, Aqdas



Solution 1:[1]

This:

const result = _.assign(..._.flatMap(val, (seats, busKey) =>
  _.flatMap(seats, (content, seatKey) =>
    _.mapKeys(content.Bookings, (_, bookingKey) =>
      _.join([busKey, seatKey, bookingKey], '_')))
))

Outputs this:

{
  Bus-1_Seat1_21032022: {
    BookedAt: "21/03/2022 3:43 PM",
    BookedBy: "Jon Doe"
  },
  Bus-1_Seat1_22032022: {
    BookedAt: "21/03/2022 9:43 PM",
    BookedBy: "James"
  },
  Bus-1_Seat2_20032022: {
    BookedAt: "21/03/2022 3:43 PM",
    BookedBy: "Elijah"
  },
  Bus-1_Seat2_21032022: {
    BookedAt: "21/03/2022 3:43 PM",
    BookedBy: "Scott"
  },
  Bus-1_Seat3_22032022: {
    BookedAt: "22/03/2022 02:41 AM",
    BookedBy: "Williams"
  },
  Bus-2_Seat1_22032022: {
    BookedAt: "22/03/2022 02:39 AM",
    BookedBy: "Lucas"
  }
}

Step-by-step:

  1. Apply flatMap on val to get the seats and key of the respective bus
  2. Apply flatMap on the seats to get the content of each seat and its key
  3. Get the bookings
  4. Apply mapKeys on the bookings to avoid collisions on the final object. This is why we extracted the keys on each level. Assuming a valid input object, the keys will be unique.
  5. Use assign on the result with the spread operator to merge everything into a single object

To reverse the process, something like this:

const output = {}

_.forEach(_.toPairs(result), ([key, value]) => {
  const keys = _.split(key, '_')
  _.set(output, keys, value)
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1