https://kotlinlang.org logo
#stdlib
Title
# stdlib
n

Nick

05/29/2022, 7:20 PM
I’d like to create a scheduler app that contains a list of events. Each event has a
startDate
and an
endDate
. I’d like to determine which events overlap so I can place events in a different column. Is there a way to apply some sort of
groupBy
function to accomplish a way for me to group them?
e

ephemient

05/29/2022, 7:30 PM
overlapping ranges are not transitive so this requires a different approach than groupBy
👍 1
n

Nick

05/29/2022, 7:31 PM
Darn. Any suggestions?
e

ephemient

05/29/2022, 7:31 PM
a

asad.awadia

05/30/2022, 3:16 PM
Might also be able to sort by start time and use a stack -- repurpose this interview question https://www.techiedelight.com/merging-overlapping-intervals/
👍 1
n

Nick

05/30/2022, 3:16 PM
Oh thanks!
a

andries.fc

05/31/2022, 9:34 AM
n

Nick

05/31/2022, 2:29 PM
Thanks @andries.fc! If I have a list of these:
Copy code
data class Event(val id: Int, val startDate: LocalDate, val endDate: LocalDate, val name: String)
How would I use your function?
a

andries.fc

05/31/2022, 2:30 PM
Will have a look just in the road
👍 1
@Nick here is simplification for your use case: https://gist.github.com/andriesfc/20412b74bad98d4cd98f5b374b25978a
n

Nick

06/01/2022, 6:57 AM
❤️❤️❤️❤️❤️❤️!!!
Thanks so much.
It looks great but I'll try it out tomorrow!
a

andries.fc

06/01/2022, 6:58 AM
no problem.. just make sure i've covered all the edge cases in the
Event.overlap()
function before just using it. did not write any test cases.
e

ephemient

06/01/2022, 7:08 AM
a. would be much simpler and easier to verify if written as
Copy code
fun Event.overlap(other: Event): Boolean = startDate <= other.endDate && endDate >= other.startDate
b. there's no reason to use a fold,
Copy code
val overlappingEvents = buildList {
    for (event in events) // ...
}
c. the approach is just wrong,
Copy code
val events = listOf(
    Event(1, LocalDate("2022-04-20"), LocalDate("2022-04-23"), "event-1"),
    Event(2, LocalDate("2022-04-20"), LocalDate("2022-04-21"), "event-2"),
    Event(3, LocalDate("2022-04-22"), LocalDate("2022-04-23"), "event-3"),
).sortedBy(Event::startDate)
returns two disjoint groups instead of one
it's not that hard to borrow from a naïve interval tree and simplify (assuming you only need to build the overlapping structure once, not add or make queries later on), https://pl.kotl.in/gygTr_6x3. but if you want to be able to add and remove events dynamically, you really do need a proper interval tree implementation
❤️ 1
2 Views