Nick

    Nick

    3 months ago
    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

    3 months ago
    overlapping ranges are not transitive so this requires a different approach than groupBy
    Nick

    Nick

    3 months ago
    Darn. Any suggestions?
    e

    ephemient

    3 months ago
    asad.awadia

    asad.awadia

    3 months ago
    Might also be able to sort by start time and use a stack -- repurpose this interview question https://www.techiedelight.com/merging-overlapping-intervals/
    Nick

    Nick

    3 months ago
    Oh thanks!
    a

    andries.fc

    3 months ago
    Nick

    Nick

    3 months ago
    Thanks @andries.fc! If I have a list of these:
    data class Event(val id: Int, val startDate: LocalDate, val endDate: LocalDate, val name: String)
    How would I use your function?
    a

    andries.fc

    3 months ago
    Will have a look just in the road
    @Nick here is simplification for your use case: https://gist.github.com/andriesfc/20412b74bad98d4cd98f5b374b25978a
    Nick

    Nick

    3 months ago
    ❤️❤️❤️❤️❤️❤️!!!
    Thanks so much.
    It looks great but I'll try it out tomorrow!
    a

    andries.fc

    3 months ago
    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

    3 months ago
    a. would be much simpler and easier to verify if written as
    fun Event.overlap(other: Event): Boolean = startDate <= other.endDate && endDate >= other.startDate
    b. there's no reason to use a fold,
    val overlappingEvents = buildList {
        for (event in events) // ...
    }
    c. the approach is just wrong,
    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