I have a list of time slots of an hour each and a list of slot bookings stored in Firestore for the same day. I now need to show availability of free slots to the user. So I am running the below code. It works fine if there is only one slot in a day, and it is booked. But it crashes with an index out of bounds error if there are more slots in a day and one of them is booked. Have spent multiple hours on this tried iterators and dont know why this is happening. Any solutions please?
Please note: i have looked at the below link, didnt work in my case:
val existingBookingsList: List<Booking> = it.toObjects(Booking::class.java)
val newAvailableList: MutableList<String> = listOfAvailableSlots
for (booking in existingBookingsList) {
//change availability of the time slots
val endTimeOfAppointment = createTime(booking.getstartTime()!!)
//add duration to time stored in Minutes
servDuration = booking.getduration()!!.toInt()
if (servDuration == 0) {
durhrs = 0
durmins = 0
} else if (servDuration < 60) {
durmins = servDuration
durhrs = 0
} else {
val hrs: Int = servDuration / 60
val mins = servDuration - (hrs * 60)
durhrs = hrs
durmins = mins
}
endTimeOfAppointment.add(Calendar.HOUR_OF_DAY, durhrs)
endTimeOfAppointment.add(Calendar.MINUTE, durmins)
//Above is getting the endTime for each slot that has been booked for a particular date
//below is looping the end time over the slots that can be booked to identify and remove the overlap
//Error occurs on this line val hour = listOfAvailableSlots[j] - Index out of bounds index 2 and size is 1
for (j in 0 until listOfAvailableSlots.size) {
val hour = listOfAvailableSlots[j]
val endTime = createTime(hour)
if (endTimeOfAppointment.compareTo(endTime) >= 0) {
newAvailableList.removeAt(j)
}
}
}
CodePudding user response:
there are several problems in the code.
At the line val newAvailableList: MutableList<String> = listOfAvailableSlots you are not initializing a new list containing the values of listOfAvailableSlots. You are assigning the pointer of listOfAvailableSlots to newAvailableList so every action you perform on newAvailableList is reflected to listOfAvailableSlots. The easiest way to copy a list to another variable is using .toMutableList(). It works even if the source list is already mutable. val newAvailableList: MutableList<String> = listOfAvailableSlots.toMutableList()
The code below can be modified
for (j in 0 until listOfAvailableSlots.size) {
val hour = listOfAvailableSlots[j]
val endTime = createTime(hour)
if (endTimeOfAppointment.compareTo(endTime) >= 0) {
newAvailableList.removeAt(j)
}
}
to this
for(availableSlot in listOfAvailableSlot) {
val endTime = createTime(availableSlot)
if(endTimeOfAppointment.compareTo(endTime) >= 0) { //consider to use greaterThan or lessThan
newAvailableList.remove(availableSlot)
}
}
which is safer than the previous.
In the same way you can use the filter function:
newAvailableList.filter { endTimeOfAppointment.compareTo(createTime(it) >= 0) }
Try to clean your code and let us know if you solved the problem
