Kotlin Aggregate operations
When we work with collections like Lists or Arrays in Kotlin, sometimes we want to perform an operation on the entire collection rather than on individual elements. These are called aggregate operations because they "aggregate" (or combine) the collection data to give us a single result, such as a total, minimum, maximum, or average. Kotlin provides many built-in functions to perform these kinds of operations easily.
1. Basic Aggregate Functions
- count() function is used to returns the number of elements.
- sum() function is used to returns the sum of elements in the collection of numbers.
- min() functions are used to return the smallest element.
- max() functions are used to return the largest element.
- average() function is used to returns the average value of elements in the collection of numbers.
Example:
fun main() {
val numbers = listOf(4, 8, 15, 16, 23, 42, 50, 43)
println("Count the number of elements in the list: ${numbers.count()}")
println("Sum of the elements in the list: ${numbers.sum()}")
println("Min value in the list: ${numbers.min()}")
println("Max value in the list: ${numbers.max()}")
println("Average of all elements in the list: ${numbers.average()}")
}
Output:
Count the number of elements in the list: 8
Sum of the elements in the list: 201
Min value in the list: 4
Max value in the list: 50
Average of all elements in the list: 25.125
2. Aggregate Functions with Lambda Expressions
- sumBy() - This calculates the sum of the values returned by the lambda expression. It’s useful when we want to process each element before summing.
- sumByDouble() - Similar to sumBy(), but works with Double values.
Example: sumBy() and sumByDouble()
fun main() {
val numbers = listOf(4, 8, 15, 16, 23, 42, 50, 43)
val sumByResult = numbers.sumBy { it * 3 }
val sumByDoubleResult = numbers.sumByDouble { it / 2.0 }
println("Multiply each element with 3 and sum: $sumByResult")
println(sumByDoubleResult)
}
Output:
Multiply each element with 3 and sum: 603
100.5
minBy() and maxBy() Functions
- minBy() - returns the element which has the smallest value according to the given selector.
- maxBy() - returns the element with the largest value according to the selector.
Note: In latest Kotlin versions, these are renamed to minByOrNull() and maxByOrNull().
minWith() and maxWith() Functions
These functions return the minimum or maximum element using a custom Comparator.
Example: minBy() and maxWith()
fun main() {
val numbers = listOf(4, 8, 15, 16, 23, 42, 50, 12)
val words = listOf("Apple", "Football", "Sun", "Moon")
val minByResult = numbers.minByOrNull { it % 10 }
val maxWithResult = words.maxWithOrNull(compareBy { it.length })
println("Minimum remainder returned by: $minByResult")
println("String with max length is: $maxWithResult")
}
Output:
Minimum remainder returned by: 12
String with max length is: Football
3. Fold and Reduce Functions
Sometimes we want to accumulate a value by going through all the elements of the collection. For this, Kotlin provides fold() and reduce() functions.
- fold() - It takes an associative binary operator function as parameter and will use it to collapse elements from the collection. .
- foldRight() - It work in a way similar to fold(). The order for traversing the elements in the collection is from right to left.
- foldIndexed() - It is used to get access of the current index while iterating.
- foldRightIndexed() : It work in a way similar to foldIndexed(). The order for traversing the elements in the collection is from right to left
- reduce() - reduces the array to a single value. It executes a provided function for each value of the array.
- reduceRight() - It work in a way similar to reduce(). The order for removing of the elements in the collection is from right to left.
- reduceIndexed() - accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element with its index in the given collection.
- reduceRightIndexed() - It work in a way similar to reduceIndexed(). The order in the collection is from right to left.
Example: fold() and reduce() Functions
fun main() {
val numbers = listOf(4, 8, 15, 16, 23, 42, 50, 45)
val foldResult = numbers.fold(0) { acc, num -> acc + num }
val reduceResult = numbers.reduce { acc, num -> acc + num }
println("The sum of all elements using fold: $foldResult")
println("The sum of all elements using reduce: $reduceResult")
}
Output:
The sum of all elements using fold: 203
The sum of all elements using reduce: 203
Example: foldRight() Function
fun main() {
val numbers = listOf(4, 8, 15, 16, 23, 42, 50, 45)
val foldRightResult = numbers.foldRight(0) { num, acc -> acc + num }
println("The sum of the numbers from the right side: $foldRightResult")
}
Output:
The sum of the numbers from the right side: 203
Example: foldIndexed() and foldRightIndexed()
fun main() {
val numbers = listOf(4, 8, 15, 16, 23, 42, 50, 45)
val foldIndexedResult = numbers.foldIndexed(0) { index, acc, num ->
if (num % 2 == 0) acc + num else acc
}
val foldRightIndexedResult = numbers.foldRightIndexed(0) { index, num, acc ->
if (num % 2 == 0) acc + num else acc
}
println("Sum of even numbers: $foldIndexedResult")
println("Sum of even numbers from right side: $foldRightIndexedResult")
}
Output:
Sum of even numbers: 126
Sum of even numbers from right side: 126