Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sum multiple elements after grouping in Kotlin

Tags:

kotlin

I have a list of objects A (alist).

A { 
  val b : Int
  val c1 : Int
  val c2 : Int
  val d1 : Int
  val d2 : Int
}

and I want to group them by b and calculate sum of c1+c2 and d1+d2 on each group and put the results in list of E objects elist.

E {
  val sum_of_c_types : Int
  val sum_of_d_types : Int
}

How do I achieve in kotlin using any collection inbuilt function?

note:

I know I can do it with reduce function and create temporary A objects, but this is important to dont use temporary A object in code.

like image 900
Hamid Ghasemi Avatar asked Dec 18 '17 13:12

Hamid Ghasemi


People also ask

What is aggregate in Kotlin?

Groups elements from the Grouping source by key and applies operation to the elements of each group sequentially, passing the previously accumulated value and the current element as arguments, and stores the results in a new map. The key for each element is provided by the Grouping. keyOf function.

How do you sum a list in Kotlin?

A simple solution to calculate the sum of all elements in a List is calling the sum() function. It is available for a list of all numeric data types. i.e, Int , Long , Float , Double , Byte , Short . Note that as of Kotlin 1.5, sumBy() function is deprecated.

How to group by in Kotlin?

The Kotlin standard library provides extension functions for grouping collection elements. The basic function groupBy() takes a lambda function and returns a Map . In this map, each key is the lambda result and the corresponding value is the List of elements on which this result is returned.

How to group collection elements in Kotlin?

The Kotlin standard library provides extension functions for grouping collection elements. The basic function groupBy () takes a lambda function and returns a Map. In this map, each key is the lambda result and the corresponding value is the List of elements on which this result is returned.

How do you sum by in Kotlin?

Note that as of Kotlin 1.5, sumBy () function is deprecated. You should use the sumOf () function instead. Alternatively, you can transform each object of the element to the corresponding field using the map () function. Finally, return the sum using the sum () function.

What is groupby in Kotlin and how it works?

How groupBy works in Kotlin? The groupby function is one of the built-in functions to perform the grouping operations with the specific data that can be achieved using the customized filters even though it can be applied in the data.

How do you group a list of elements in Python?

The basic function groupBy () takes a lambda function and returns a Map. In this map, each key is the lambda result and the corresponding value is the List of elements on which this result is returned. This function can be used, for example, to group a list of String s by their first letter.


1 Answers

I've solved it by using a sequence of groupBy, map and sumBy. It's 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:

With Grouping (using groupingBy instead of groupBy), it looks even better because you don't have to handle map entities:

 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)
    }
like image 179
s1m0nw1 Avatar answered Dec 22 '22 18:12

s1m0nw1