Hey there, is there a stdlib function to chunk a l...
# stdlib
h
Hey there, is there a stdlib function to chunk a list by an attribute which is changing? Something along
Copy code
fun <T, K> List<T>.chunkBy(selector: (T) -> K): List<List<T>> {
    val result = mutableListOf<MutableList<T>>()
    var lastKey: K? = null
    for (item in this) {
        if (selector(item) != lastKey) result.add(mutableListOf(item)).also { lastKey = selector(item) }
        else result.last().add(item)
    }
    return result
}

 data class Person(val age: Int)

val persons = listOf(Person(23), Person(12), Person(23), Person(23), Person(22))
val chunkBy = persons.chunkBy { it.age }
but maybe its already part of stdlib?
j
what is the expected output there? a list containing five, single-item lists?
oh the wrapping confused me
so it would be a list of one, one, two, one
as far as i can there's no really good way to do this with built-in operators that isn't wildly more complex and opaque than your dead-simple imperative loop
I'm not sure it should be named
chunkedBy
. It's almost like a
runningGroupBy
or something.
h
Thanks for your input @jw
a
There's a ticket requesting
.chunked()
, but with a predicate https://youtrack.jetbrains.com/issue/KT-41648
👀 1
👍 2
k
How is this different than using
groupBy
and then grabbing the values from the resulting map?
Copy code
val peopleByAge = persons.groupBy { it.age }.values
j
The original example
Copy code
listOf(Person(23), Person(12), Person(23), Person(23), Person(22))
should produce
Copy code
[
  [Person(23)],
  [Person(12)],
  [Person(23), Person(23)],
  [Person(22)],
]
your method would combine the two separate groupings of the "23"s