如何在Kotlin中分组后总结多个元素
我有一个对象列表( alist
)。
A { val b : Int val c1 : Int val c2 : Int val d1 : Int val d2 : Int }
我想用b
对它们进行分组,并计算每个组的c1+c2
和d1+d2
和,并将结果放在E个对象列表中。
E { val sum_of_c_types : Int val sum_of_d_types : Int }
如何使用任何集合内置函数在kotlin中实现?
注意:
我知道我可以使用reduce
函数来创建临时A对象,但是这对于不要在代码中使用临时对象很重要。
我已经通过使用groupBy
, map
和sumBy
的序列来解决它。 这可能不是我想的最干净的解决方案。
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) { 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 = 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}") } }
结果是:
Group b=1: E(sumC=10, sumD=18) Group b=2: E(sumC=4, sumD=4) Group b=3: E(sumC=3, sumD=3)
编辑 :
使用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) }
我认为这只是折叠分组
fun group(a: List) = a.groupingBy(A::b).fold(E(0, 0), { acc, elem -> E(acc.sum_of_c_types + elem.c1 + elem.c2, acc.sum_of_d_types + elem.d1 + elem.d2) })
我通过下面的代码解决了它:
alist.groupby { b }. mapValues { it.value.map { E(it.c1+it.c2, it.d1+it.d2) }.reduce { acc, e -> E(acc.sum_of_c_types + e.sum_of_c_types, acc.sum_of_d_types + e.sum_of_d_types) }.values