https://kotlinlang.org logo
Title
m

Marc Javier

12/05/2021, 10:59 PM
groupingBy method
e

ephemient

12/05/2021, 11:03 PM
that can give total counts but that's different than RLE
m

Marc Javier

12/05/2021, 11:06 PM
whops...thought that last two elements were D😫
h

holgerbrandl

12/05/2021, 11:16 PM
Yep, a simple grouping won't do it, as elements may show up more than once in the run. I was hoping for some clever
fold
ing or similar, but have no clue how to implement it elegantly.
m

Michael Böiers

12/06/2021, 9:51 PM
listOf("a", "a", "b", "c", "c", "a", "a")
    .fold(mutableListOf<Pair<String, Int>>()) { acc, s ->
        if (acc.isEmpty() || acc.last().first != s) 
            acc.add(s to 1) 
        else 
            acc[acc.size-1] = s to acc.last().second + 1
        acc 
    }.toList()
fun <T> Iterable<T>.runLengths() = fold(mutableListOf<Pair<T, Int>>()) { acc, t ->
    acc.apply {
        if (acc.isEmpty() || acc.last().first != t)
            acc.add(t to 1)
        else
            acc[acc.size-1] = t to acc.last().second + 1
    }
}.toList()

listOf("a", "a", "b", "c", "c", "a", "a")
    .runLengths()
e

ephemient

12/06/2021, 9:55 PM
there's not any good reason to use a fold there - you're never changing what acc references
m

Michael Böiers

12/06/2021, 10:04 PM
🙂
fun <T> Iterable<T>.runLengths() = mutableListOf<Pair<T, Int>>().run {
    for (t in this@runLengths)
        if (isEmpty() || last().first != t) add(t to 1) else set(size - 1, t to last().second + 1)
    toList()
}

listOf("a", "a", "b", "c", "c", "a", "a").runLengths()
Or rather
fun <T> Iterable<T>.runLengths() = buildList<Pair<T, Int>> {
    for (t in this@runLengths)
        if (isEmpty() || last().first != t) add(t to 1) else set(size - 1, t to last().second + 1)
}

listOf("a", "a", "b", "c", "c", "a", "a").runLengths()
e

ephemient

12/06/2021, 10:09 PM
I think my https://kotlinlang.slack.com/archives/C0B8MA7FA/p1638746141245300?thread_ts=1638744707.244600&amp;cid=C0B8MA7FA has advantages as it doesn't generate more garbage than necessary and can be easily adapted to work as Sequence<T>.() -> Sequence<Pair<T, Int>>, but works either way
🙌 1