Home > OS >  Compare two arrays to figure out the available time slots for a booking system
Compare two arrays to figure out the available time slots for a booking system

Time:12-29

I have a booking array which has all the slots for particular staff Id which are filed

[
            {
                "staffId": 1,
                "bookedslots": [
                    {
                        "startTime": "19:45",
                        "endTime": "21:15"
                    },
                    {
                        "startTime": "07:45",
                        "endTime": "09:00"
                    }
                ]
            },
            {
                "staffId": 2,
                "bookedslots": [
                    {
                        "startTime": "07:45",
                        "endTime": "09:15"
                    },
                    {
                        "startTime": "09:45",
                        "endTime": "10:15"
                    }
                ]
            }
        ]
    ]

I have another array of all the slots with particular time gap

const available=  [
      {
        startTime: '08:00',
        endTime: '08:45',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '08:45',
        endTime: '09:30',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '09:30',
        endTime: '10:15',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '10:15',
        endTime: '11:00',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '11:00',
        endTime: '11:45',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '11:45',
        endTime: '12:30',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '12:30',
        endTime: '13:15',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '13:15',
        endTime: '14:00',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '14:00',
        endTime: '14:45',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '14:45',
        endTime: '15:30',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '15:30',
        endTime: '16:15',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '16:15',
        endTime: '17:00',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '17:00',
        endTime: '17:45',
        isBooked: false,
        date: '2021-12-09'
      },
    [
      {
        startTime: '08:00',
        endTime: '08:45',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '08:45',
        endTime: '09:30',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '09:30',
        endTime: '10:15',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '10:15',
        endTime: '11:00',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '11:00',
        endTime: '11:45',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '11:45',
        endTime: '12:30',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '12:30',
        endTime: '13:15',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '13:15',
        endTime: '14:00',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '14:00',
        endTime: '14:45',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '14:45',
        endTime: '15:30',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '15:30',
        endTime: '16:15',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '16:15',
        endTime: '17:00',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '17:00',
        endTime: '17:45',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '17:45',
        endTime: '18:30',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '18:30',
        endTime: '19:15',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '19:15',
        endTime: '20:00',
        isBooked: false,
        date: '2021-12-09'
      },
      {
        startTime: '20:00',
        endTime: '20:45',
        isBooked: false,
        date: '2021-12-09'
      }
    ]

I want the filtered available slots whose startTime and Endtime doesn't lies in between any starTime or endTime in booked array of either staff

Expected Output

[
  {
    startTime: '08:00',
    endTime: '08:45',
    isBooked: true, // as for both the staffs this slot is booked (07:45 -09:00))) && (07:45 -09:15))
    date: '2021-12-09'
  },
  {
    startTime: '08:45',
    endTime: '09:30',
    isBooked: true, // as for both the staffs this slot is booked (07:45 -09:00))) && (07:45 -09:15))
    date: '2021-12-09'
  },
  {
    startTime: '09:30',
    endTime: '10:15',
    isBooked: false, // as for staff ID 2 this slot  is booked but for staff 1 its empty ,so it can take the booking
    date: '2021-12-09'
  },
  -----
  {
    startTime: '20:00',
    endTime: '20:45',
    isBooked: false,  // As only for staff Id 1 its blocked ,staff Id 2 its still empty
    date: '2021-12-09'
  }
]

What I tried

const emptyData = [

  {
    startTime: '08:00',
    endTime: '08:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '08:45',
    endTime: '09:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '09:30',
    endTime: '10:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '10:15',
    endTime: '11:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:00',
    endTime: '11:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:45',
    endTime: '12:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '12:30',
    endTime: '13:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '13:15',
    endTime: '14:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:00',
    endTime: '14:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:45',
    endTime: '15:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '15:30',
    endTime: '16:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '16:15',
    endTime: '17:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '17:00',
    endTime: '17:45',
    isBooked: false,
    date: '2021-12-09'
  },
  [{
      startTime: '08:00',
      endTime: '08:45',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '08:45',
      endTime: '09:30',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '09:30',
      endTime: '10:15',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '10:15',
      endTime: '11:00',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '11:00',
      endTime: '11:45',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '11:45',
      endTime: '12:30',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '12:30',
      endTime: '13:15',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '13:15',
      endTime: '14:00',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '14:00',
      endTime: '14:45',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '14:45',
      endTime: '15:30',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '15:30',
      endTime: '16:15',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '16:15',
      endTime: '17:00',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '17:00',
      endTime: '17:45',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '17:45',
      endTime: '18:30',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '18:30',
      endTime: '19:15',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '19:15',
      endTime: '20:00',
      isBooked: false,
      date: '2021-12-09'
    },
    {
      startTime: '20:00',
      endTime: '20:45',
      isBooked: false,
      date: '2021-12-09'
    }
  ]

  const booked = [{
      "staffId": 1,
      "bookedslots": [{
          "startTime": "19:45",
          "endTime": "21:15"
        },
        {
          "startTime": "07:45",
          "endTime": "09:00"
        }
      ]
    },
    {
      "staffId": 2,
      "bookedslots": [{
          "startTime": "07:45",
          "endTime": "09:15"
        },
        {
          "startTime": "09:45",
          "endTime": "10:15"
        }
      ]
    }
  ]
]


const checkInbookingslots = (time) => {

    booked.some(ele => {
        ele.bookedslots.some(e => {

            if (moment(time).isBetween(moment(e.startTime), moment(e.endTime)) {
                // I am not able to figure out the break condition and when to return
              }

            })





        })





      return false;

    }




    const output = emptyData.map(ele => 
     ele.check= (checkInbookingslots(ele.starTime)&&checkInbookingslots(ele.endTime))

     })
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

I am looking for an optimal solution ,please help me out .Thanks

CodePudding user response:

You can use combination of Array.prototype.every() and Array.prototype.some() as follows:

(Note that you need to pass the format string 'h:mm a' to the moment() function to avoid error when converting time string to the Moment object)

const emptyData = [
  {
    startTime: '08:00',
    endTime: '08:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '08:45',
    endTime: '09:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '09:30',
    endTime: '10:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '10:15',
    endTime: '11:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:00',
    endTime: '11:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:45',
    endTime: '12:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '12:30',
    endTime: '13:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '13:15',
    endTime: '14:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:00',
    endTime: '14:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:45',
    endTime: '15:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '15:30',
    endTime: '16:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '16:15',
    endTime: '17:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '17:00',
    endTime: '17:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '08:00',
    endTime: '08:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '08:45',
    endTime: '09:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '09:30',
    endTime: '10:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '10:15',
    endTime: '11:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:00',
    endTime: '11:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:45',
    endTime: '12:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '12:30',
    endTime: '13:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '13:15',
    endTime: '14:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:00',
    endTime: '14:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:45',
    endTime: '15:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '15:30',
    endTime: '16:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '16:15',
    endTime: '17:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '17:00',
    endTime: '17:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '17:45',
    endTime: '18:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '18:30',
    endTime: '19:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '19:15',
    endTime: '20:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '20:00',
    endTime: '20:45',
    isBooked: false,
    date: '2021-12-09'
  }
]

const booked = [{
  "staffId": 1,
  "bookedslots": [{
    "startTime": "19:45",
    "endTime": "21:15"
    },
    {
      "startTime": "07:45",
      "endTime": "09:00"
    }
  ]
  },
  {
    "staffId": 2,
    "bookedslots": [{
      "startTime": "07:45",
      "endTime": "09:15"
    },
      {
        "startTime": "09:45",
        "endTime": "10:15"
      }
    ]
  }
]

const checkInbookingslots = (startTime, endTime) =>
  booked.every(ele =>
    ele.bookedslots.some(e => moment(startTime, 'h:mm a').isBetween(moment(e.startTime, 'h:mm a'), moment(e.endTime, 'h:mm a')))
    || ele.bookedslots.some(e => moment(endTime, 'h:mm a').isBetween(moment(e.startTime, 'h:mm a'), moment(e.endTime, 'h:mm a')))
  )

const output = emptyData.map(ele => {
  ele.isBooked = checkInbookingslots(ele.startTime, ele.endTime)
  return ele
})

console.log(output)

Output:

[
  {
    startTime: '08:00',
    endTime: '08:45',
    isBooked: true,
    date: '2021-12-09'
  },
  {
    startTime: '08:45',
    endTime: '09:30',
    isBooked: true,
    date: '2021-12-09'
  },
  {
    startTime: '09:30',
    endTime: '10:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '10:15',
    endTime: '11:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:00',
    endTime: '11:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:45',
    endTime: '12:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '12:30',
    endTime: '13:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '13:15',
    endTime: '14:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:00',
    endTime: '14:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:45',
    endTime: '15:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '15:30',
    endTime: '16:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '16:15',
    endTime: '17:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '17:00',
    endTime: '17:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '08:00',
    endTime: '08:45',
    isBooked: true,
    date: '2021-12-09'
  },
  {
    startTime: '08:45',
    endTime: '09:30',
    isBooked: true,
    date: '2021-12-09'
  },
  {
    startTime: '09:30',
    endTime: '10:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '10:15',
    endTime: '11:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:00',
    endTime: '11:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '11:45',
    endTime: '12:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '12:30',
    endTime: '13:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '13:15',
    endTime: '14:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:00',
    endTime: '14:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '14:45',
    endTime: '15:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '15:30',
    endTime: '16:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '16:15',
    endTime: '17:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '17:00',
    endTime: '17:45',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '17:45',
    endTime: '18:30',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '18:30',
    endTime: '19:15',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '19:15',
    endTime: '20:00',
    isBooked: false,
    date: '2021-12-09'
  },
  {
    startTime: '20:00',
    endTime: '20:45',
    isBooked: false,
    date: '2021-12-09'
  }
]

CodePudding user response:

Moment is not necessary for comparing time. You can just check if a.start < b.end && a.end > b.start for a and b to overlap.

Then it is trivial. You want a time slot to be included if it is booked for SOME staff. And you want isBooked to be true of it is booked for EVERY staff. Array.some() and Array.every() come in handy. Together with filter and map you get one line of very intuitive code to do your job.

That being said this would be quite inefficient as it would loop through the arrays many time. If you opt for performance, you may replace filter and map with a single reduce, and replace some and every with a single pass of for loop.

const staffs=[{"staffId":1,"bookedslots":[{"startTime":"19:45","endTime":"21:15"},{"startTime":"07:45","endTime":"09:00"}]},{"staffId":2,"bookedslots":[{"startTime":"07:45","endTime":"09:15"},{"startTime":"09:45","endTime":"10:15"}]}];
const available=[{startTime:'08:00',endTime:'08:45',isBooked:!1,date:'2021-12-09'},{startTime:'08:45',endTime:'09:30',isBooked:!1,date:'2021-12-09'},{startTime:'09:30',endTime:'10:15',isBooked:!1,date:'2021-12-09'},{startTime:'10:15',endTime:'11:00',isBooked:!1,date:'2021-12-09'},{startTime:'11:00',endTime:'11:45',isBooked:!1,date:'2021-12-09'},{startTime:'11:45',endTime:'12:30',isBooked:!1,date:'2021-12-09'},{startTime:'12:30',endTime:'13:15',isBooked:!1,date:'2021-12-09'},{startTime:'13:15',endTime:'14:00',isBooked:!1,date:'2021-12-09'},{startTime:'14:00',endTime:'14:45',isBooked:!1,date:'2021-12-09'},{startTime:'14:45',endTime:'15:30',isBooked:!1,date:'2021-12-09'},{startTime:'15:30',endTime:'16:15',isBooked:!1,date:'2021-12-09'},{startTime:'16:15',endTime:'17:00',isBooked:!1,date:'2021-12-09'},{startTime:'17:00',endTime:'17:45',isBooked:!1,date:'2021-12-09'},{startTime:'08:00',endTime:'08:45',isBooked:!1,date:'2021-12-09'},{startTime:'08:45',endTime:'09:30',isBooked:!1,date:'2021-12-09'},{startTime:'09:30',endTime:'10:15',isBooked:!1,date:'2021-12-09'},{startTime:'10:15',endTime:'11:00',isBooked:!1,date:'2021-12-09'},{startTime:'11:00',endTime:'11:45',isBooked:!1,date:'2021-12-09'},{startTime:'11:45',endTime:'12:30',isBooked:!1,date:'2021-12-09'},{startTime:'12:30',endTime:'13:15',isBooked:!1,date:'2021-12-09'},{startTime:'13:15',endTime:'14:00',isBooked:!1,date:'2021-12-09'},{startTime:'14:00',endTime:'14:45',isBooked:!1,date:'2021-12-09'},{startTime:'14:45',endTime:'15:30',isBooked:!1,date:'2021-12-09'},{startTime:'15:30',endTime:'16:15',isBooked:!1,date:'2021-12-09'},{startTime:'16:15',endTime:'17:00',isBooked:!1,date:'2021-12-09'},{startTime:'17:00',endTime:'17:45',isBooked:!1,date:'2021-12-09'},{startTime:'17:45',endTime:'18:30',isBooked:!1,date:'2021-12-09'},{startTime:'18:30',endTime:'19:15',isBooked:!1,date:'2021-12-09'},{startTime:'19:15',endTime:'20:00',isBooked:!1,date:'2021-12-09'},{startTime:'20:00',endTime:'20:45',isBooked:!1,date:'2021-12-09'}]

function getTime(str)
{
    const [h,m] = str.split(":").map(it => Number(it));
    return h * 60   m;
}

function isTimeslotBookedForStaff(timeslot,staff)
{
    for(let slot of staff.bookedslots)
    {
        if(getTime(timeslot.startTime) < getTime(slot.endTime) && getTime(timeslot.endTime) > getTime(slot.startTime))
        {
            return true;
        }
    }
    return false;
}

//redablility version
const output = available.filter(slot => staffs.some(staff => isTimeslotBookedForStaff(slot,staff)))
                        .map(slot => ({...slot,isBooked: staffs.every(staff => isTimeslotBookedForStaff(slot,staff)) }));

console.log(output);

//performance version
let output2 = available.reduce((acc,slot)=>{
    let isSomeBooked = false;
    let isAllBooked = true;
    for(let staff of staffs)
    {
        let isBooked = isTimeslotBookedForStaff(slot,staff);
        isSomeBooked = isSomeBooked || isBooked;
        isAllBooked = isAllBooked && isBooked;
    }
    if(isSomeBooked)
    {
        acc.push({...slot,isBooked: isAllBooked})
    }
    return acc;
},[]);

console.log(output2);

  • Related