I solved this using sequence groupBy
, map
and sumBy
. This is probably not the cleanest solution I guess.
data class A(val b: Int,
val c1: Int,
val c2: Int,
val d1: Int,
val d2: Int)
data class E(val sumC: Int, val sumD: Int)
fun main(args: Array<String>) {
val alist = listOf(A(1, 2, 1, 4, 5), A(1, 3, 4, 6, 3), A(2, 2, 2, 2, 2), A(3, 1, 2, 1, 2))
val grouped: Map<Int, E> = alist.groupBy(A::b).mapValues {
E(it.value.sumBy { it.c1 + it.c2 }, it.value.sumBy { it.d1 + it.d2 })
}
grouped.forEach {
println("Group b=${it.key}: ${it.value}")
}
}
Results in:
Group b=1: E(sumC=10, sumD=18)
Group b=2: E(sumC=4, sumD=4)
Group b=3: E(sumC=3, sumD=3)
Edit
Grouping
( groupingBy
groupBy
), , :
val grouped = alist.groupingBy(A::b).aggregate { _, acc: E?, e, _ ->
E((acc?.sumC ?: 0) + e.c1 + e.c2, (acc?.sumD ?: 0) + e.d1 + e.d2)
}