is there a neat way to group by value and respect ...
# announcements
b
is there a neat way to group by value and respect adjacency? e.g. ["aa", "aa", "a", "aa"].adjacentGroupBy(String::length) should return [["aa", "aa"], ["a"], ["aa"]]
t
b
@thanksforallthefish that requires a size
i thought about going from ["aa", "aa", "a", "aa"] to [["aa"], ["aa"], ["a"], ["aa"]] and then use fold to manipulate the array
but that seems like a bad idea with lots of useless allocation
h
https://pl.kotl.in/2TXgCoR3q ? (But yeah, that's not efficient)
b
or something like
Copy code
fun <T, V> adjacentGroupBy(values: Iterable<T>, criterium: (T) -> V): List<List<T>> {
    val result = ArrayList<ArrayList<T>>()
    for (value in values) {
        if (result.isEmpty()) {
            result.add(arrayListOf(value))
        } else {
            if (criterium(result.last().last()) == criterium(value)) {
                result.last().add(value)
            } else {
                result.add(arrayListOf(value))
            }
        }
    }
    return result
}
but that's ugly
t
I think the way
windowed
works, you can set a window size of 2 and a step of 1, so each element is processed along with the next one
let me see if I can come up with some code
yeah no, it gets ugly
b
funny thing is that thats the default implementation in Haskell for groupBy
and I can't find it in the stdlib
h
In Kotlin,
groupBy
always means "assign to some common key".
b
yeah, turns it into a map
afaik its similar to java's Stream.groupingBy
a
This question is quite similar to https://kotlinlang.slack.com/archives/C0922A726/p1555991397085900 I would probably write something like
Copy code
fun <T, U> List<T>.adjacentGroupBy(selector: (T)->U) : List<List<T>> {
    return fold(mutableListOf<MutableList<T>>()) { acc, e ->
        acc.apply {
            when {
                isEmpty() -> add(mutableListOf(e))
                selector(e) == selector(last().last()) -> last().add(e)
                else -> add(mutableListOf(e))
            }
        }
    }
}
k
I'm curious, what's the use case? This gets asked about once a week but I've never come across anything like this before.
1
b
@karelpeeters grouping together opening hours: you start out with a list of: • MONDAY: 0800 1200 • TUESDAY: 0800 1200, • WEDNESDAY: 0900 1200 • THURSDAY: 0800 1200 • ... and you want to end up with: Mo-Tu: 0800 1200 We: 0900 1200 Th: 0800 1200 ...
👍 1