Hello, I'm trying to aggregate durations of a list...
# getting-started
n
Hello, I'm trying to aggregate durations of a list of events and I'm looking for a way to improve my code. Here's a simplified input:
Copy code
val modeTicks: List<Pair<Int, LocalTime>> = listOf(
    0 to LocalTime.of(11, 0), // Start at 11:00 with mode 0
    0 to LocalTime.of(11, 5), // Mode 0 again at 11:05 (same mode as previous can be reemitted because reasons)
    1 to LocalTime.of(11, 7), // Switch to mode 1 at 11:07
    2 to LocalTime.of(11, 8), // Switch to mode 2 at 11:08
    2 to LocalTime.of(11, 11), // "End" tick finishing mode is guaranteed
)
At the end, I want a
Map<Int, Duration>
that have as a key
0
,
1
or
2
, and the values should be the
Duration
each
mode
spent on. So the result should be:
{0=7m, 1=1m, 2=3m}
My implementation (playground): https://pl.kotl.in/PiIQ--HDs Any way to improve it ? Thanks 🙏
s
Does it have to use functional/immutable idioms? I think I’d just make a mutable state machine that builds the map as it goes.
Copy code
val builder = SomeBuilder()
modeTicks.forEach { (mode, time) -> builder.changeMode(mode, time) }
builder.endOfInput()
val result = builder.toMap()
implementation of
SomeBuilder
left as an exercise for the reader 😄
n
I enjoy functionnal programming more and more as I get better in Kotlin, so I was looking for a functionnal programming oriented answer indeed 😛
👍 2
w
One small tip: You can combine
zipWithNext()
and
map
Copy code
.zipWithNext { previous, current ->
      previous.mode to JavaDuration.between(previous.localTime, current.localTime).toKotlinDuration()
    }
🙌 1
💯 1
k
An alternative way:
Copy code
val assistanceModeDurations: Map<Int, Duration> = modeTicks
        .filterIndexed { i, (mode, _) ->
            (i == 0 || i == modeTicks.lastIndex || mode > modeTicks[i - 1].mode)
        }
        .zipWithNext { previous, current ->
            previous.mode to JavaDuration.between(previous.localTime, current.localTime).toKotlinDuration()
        }
        .toMap()
m
@Nino your implementation is exactly how I would make it myself, only improvement is that of Wout Werkman