In my iOS app i have a list of events that each have a start and end date. My goal is to figure out which events overlap each other - meaning, if event1 starts Mon, oct 6 @ 2:30 pm and ends at 5:30 pm and event4 starts Mon, oct 6 @ 3:30 pm. I need to know that those two events overlap.
So When downloading the data from the web, i create an array of [DateInterval]
with each EventObjects
start date and end date respectively.
My question is, what's the best way to iterate though the eventObjects array and then check if the start dates intersect with the [DateInterval]
dates?
Thank you in advance
EDIT
here is an example code..
func sortArray (){
for object in sortedEventObjectArray {
let hasConflics = zip(datesReversed, datesReversed.dropFirst()).contains(where: { $0.end > $1.start })
if hasConflics == true {
print("conflict")
} else {
print("none")
}
}
}
[sortedEventObjectArray] is an event object which contains details like the start date and end date of event - this is what i used to populate the datesReserved array of Date Intervals
[datesReversed] is an array of DateIntervals - it looks like this
[2018-11-01 06:00:00 +0000 to 2018-11-01 09:30:00 +0000, 2018-11-01 18:00:00 +0000 to 2018-11-01 19:33:00 +0000, 2018-11-01 19:33:00 +0000 to 2018-11-01 23:00:00 +0000, 2018-11-03 18:14:00 +0000 to 2018-11-03 21:44:00 +0000, 2018-11-03 18:14:00 +0000 to 2018-11-03 21:44:00 +0000, 2018-11-06 12:00:00 +0000 to 2018-11-06 13:26:00 +0000, 2018-11-06 13:27:00 +0000 to 2018-11-06 14:00:00 +0000, 2018-11-06 17:00:00 +0000 to 2018-11-06 22:00:00 +0000, 2018-11-06 18:00:00 +0000 to 2018-11-06 21:00:00 +0000, 2018-11-07 12:00:00 +0000 to 2018-11-07 14:30:00 +0000, 2018-11-07 18:30:00 +0000 to 2018-11-07 23:00:00 +0000, 2018-11-08 11:30:00 +0000 to 2018-11-08 12:59:00 +0000, 2018-11-08 12:56:00 +0000 to 2018-11-08 13:30:00 +0000, 2018-11-08 19:30:00 +0000 to 2018-11-08 22:30:00 +0000, 2018-11-09 12:30:00 +0000 to 2018-11-09 14:30:00 +0000, 2018-11-09 15:00:00 +0000 to 2018-11-09 16:00:00 +0000, 2018-11-09 16:30:00 +0000 to 2018-11-09 21:00:00 +0000, 2018-11-09 20:00:00 +0000 to 2018-11-09 21:30:00 +0000, 2018-11-10 12:30:00 +0000 to 2018-11-10 20:30:00 +0000, 2018-11-10 13:45:00 +0000 to 2018-11-10 14:30:00 +0000, 2018-11-10 18:00:00 +0000 to 2018-11-10 19:00:00 +0000]
The output i get is - (Which is wrong because its clear that some of those dates do not have scheduling conflicts )
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
conflict
An efficient solution is to sort the events by increasing start date first. Then you only have to compare each event with those that start later.
If the model object is
struct Event {
let title: String
let duration: DateInterval
}
then it could look like this (untested):
var events: [Event] = ...
events.sort(by: { $0.duration.start < $1.duration.start })
for i in events.indices.dropLast() {
for j in (i + 1)..<events.endIndex {
if events[i].duration.end > events[j].duration.start {
print(events[i].title, "overlaps with", events[j].title)
} else {
break
}
}
}
Note hat the inner loop can terminate if a non-overlapping event is found, because the events are sorted by increasing start date.
If you only need to know if any events overlap then it suffices to compare each event duration with the duration of the following event:
var events: [Event] = ...
events.sort(by: { $0.duration.start < $1.duration.start })
var hasConflicts = false
for i in events.indices.dropLast() {
if events[i].duration.end > events[i+1].duration.start {
hasConflics = true
break
}
}
Using zip
this code can be shorted to
var events: [Event] = ...
events.sort(by: { $0.duration.start < $1.duration.start })
let hasConflics = zip(events, events.dropFirst())
.contains(where: { $0.duration.end > $1.duration.start })