JSFiddle - React, Tailwind, and code Playground
by jrunning
JavaScript
const INCREMENT = 1800;
function rangeIncl(start, end, incr = INCREMENT) {
return start < end ? [start, ...rangeIncl(start + incr, end)] : [end];
}
function timeslotGroups(startTimeslot, endTimeslot, bookings) {
const [booking, ...restBookings] = bookings;
if (booking) {
if (startTimeslot < booking.from) {
// startTimeslot is before next booking.from; create available group
return [
{ available: true, timeslots: rangeIncl(startTimeslot, booking.from - INCREMENT) },
...timeslotGroups(booking.from, endTimeslot, bookings),
];
}
if (startTimeslot <= booking.to) {
// startTimeslot is between booking.from and .to; create not-available group
return [
{ available: false, timeslots: rangeIncl(booking.from, booking.to) },
...timeslotGroups(booking.to + INCREMENT, endTimeslot, restBookings),
];
}
// startTimeslot is after booking.to; try again with next booking
return timeslotGroups(startTimeslot, endTimeslot, restBookings);
}
return startTimeslot < endTimeslot ?
[ { available: true, timeslots: rangeIncl(startTimeslot, endTimeslot) } ] :
[];
}
const availableTimeslots = [
1559709000, 1559710800, 1559712600, 1559714400, 1559716200, 1559718000,
1559719800, 1559721600, 1559723400, 1559725200, 1559727000, 1559728800,
1559730600, 1559732400, 1559734200, 1559736000, 1559737800, 1559739600,
];
const bookedTimeslots = {
bookings: [
{
timestamp: {
from: 1559719800,
to: 1559723400
}
},
{
timestamp: {
from: 1559730600,
to: 1559732400
}
}
]
};
const bookings = bookedTimeslots.bookings.map(({ timestamp }) => timestamp);
const res = timeslotGroups(availableTimeslots[0], availableTimeslots[availableTimeslots.length - 1], bookings);
console.log(res);
/* DESIRED RESULT
[
{
available: true,
timeslots: [1559709000, 1559710800, 1559712600, 1559714400, 1559716200, 1559718000]
},
...