I have an availabilities
collection. Inside this collection could be a few entries that are date based for example:
{
"_id": "64b03ed794d87927a3066e13",
"startDateTime": "2023-07-07T18:00:00.000Z",
"endDateTime": "2023-07-12T15:00:00.000Z",
"availabilityType": "blackout"
}
{
"_id": "64b03eb094d87927a3066ddb",
"startDateTime": "2023-07-03T18:00:00.000Z",
"endDateTime": "2023-07-06T15:00:00.000Z",
"availabilityType": "blackout"
}
I am trying to figure out the best way to create an array of dates for the month and if there is an “availability” for some of the days, then return that within the date array. I thought about creating an array of days using javascript but then I’d have to iterate for each day to see there are any availabilities
on the day; this seems very inefficient.
Ideally what I am looking to build is something similar to the following:
[
{
"date": "2023-07-01",
"availabilityType": "available"
},
{
"date": "2023-07-02",
"availabilityType": "available"
},
{
"date": "2023-07-03",
"availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
},
{
"date": "2023-07-04",
"availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
},
{
"date": "2023-07-05",
"availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
},
{
"date": "2023-07-06",
"availabilityType": "booked" // because there was an availability entry in the collection that is marked as booked
},
... etc up to July 31
]
Any suggestions on how this might be done?
3
Answers
One approach is to pre-generate an array for the month with a default status of
"available"
for all days, then loop through the availabilities and update the relevant entries in your array. for example, Firstly, generate the array for the month:Then, update the availability data with the array data:
This assumes that
availabilities
is sorted in ascending order and does not contain overlapping intervals. If these assumptions are not true, you may need to sortavailabilities
first and add additional checks in the second loop.Here is another take on it:
As the
monthCal
object allows the dates to be found directly, without using in inner loop, this might be slightly more efficient then scanning through an array of objects.You can simply achieve this by defining a
startDate
and anendDate
to represent the range of dates for the month you want to get the details. For demo purpose, I am using July month range.Then, we will iterate over each date using a for loop, starting from the
startDate
and incrementing by one day until theendDate
.Within the loop, we check if the current date falls within the
startDateTime
andendDateTime
range of any object in the array with the availabilityTypeblackout
. If it does, theisBooked
variable is set totrue
, indicating that the date is booked. Otherwise,isBooked
remainsfalse
, indicating that the date is available.Finally, we push an object to the
allDates
array for each date, setting the date property to the formatted date string and the available property to eitherbooked
oravailable
based on the isBooked value.Live Demo :