In Java 8, there is Stream.collect which allows aggregations on collections. In Kotlin, this does not exist in the same way, other than maybe as a collection of extension f
Let's take the example solution for "Compute sum of salaries by department" given by Jayson:
val totalByDept = employees.groupBy { it.dept }.mapValues { it.value.sumBy { it.salary }}
In order to make this lazy (i.e. avoid creating an intermediate map in the groupBy step), it is not possible to use asSequence(). Instead, we must use groupingBy and fold operation:
val totalByDept = employees.groupingBy { it.dept }.fold(0) { acc, e -> acc + e.salary }
To some people this may even be more readable, since you're not dealing with map entries: the it.value part in the solution was confusing for me too at first.
Since this is a common case and we'd prefer not to write out the fold each time, it may be better to just provide a generic sumBy function on Grouping:
public inline fun Grouping.sumBy(
selector: (T) -> Int
): Map =
fold(0) { acc, element -> acc + selector(element) }
so that we can simply write:
val totalByDept = employees.groupingBy { it.dept }.sumBy { it.salary }