Collection Aggregate Operations
- and return the smallest and the largest element respectively. On empty collections, they return
null
. average()
returns the average value of elements in the collection of numbers.- returns the sum of elements in the collection of numbers.
count()
returns the number of elements in a collection.
There are also functions for retrieving the smallest and the largest elements by certain selector function or custom :
maxByOrNull()
/ take a selector function and return the element for which it returns the largest or the smallest value.maxWithOrNull()
/ take aComparator
object and return the largest or smallest element according to thatComparator
.
All these functions return null
on empty collections.
fun main() {
//sampleStart
val numbers = listOf(5, 42, 10, 4)
val min3Remainder = numbers.minByOrNull { it % 3 }
println(min3Remainder)
val strings = listOf("one", "two", "three", "four")
val longestString = strings.maxWithOrNull(compareBy { it.length })
//sampleEnd
sumBy()
applies functions that returnInt
values on collection elements.- works with functions that return
Double
.
For more specific cases, there are the functions reduce()
and that apply the provided operation to the collection elements sequentially and return the accumulated result. The operation takes two arguments: the previously accumulated value and the collection element.
The difference between the two functions is that fold()
takes an initial value and uses it as the accumulated value on the first step, whereas the first step of reduce()
uses the first and the second elements as operation arguments on the first step.
fun main() {
//sampleStart
val numbers = listOf(5, 2, 10, 4)
val sum = numbers.reduce { sum, element -> sum + element }
println(sum)
val sumDoubled = numbers.fold(0) { sum, element -> sum + element * 2 }
println(sumDoubled)
//val sumDoubledReduce = numbers.reduce { sum, element -> sum + element * 2 } //incorrect: the first element isn't doubled in the result
//println(sumDoubledReduce)
}
To apply a function to elements in the reverse order, use functions and . They work in a way similar to fold()
and reduce()
but start from the last element and then continue to previous. Note that when folding or reducing right, the operation arguments change their order: first goes the element, and then the accumulated value.
You can also apply operations that take element indices as parameters. For this purpose, use functions reduceIndexed()
and passing element index as the first argument of the operation.
fun main() {
//sampleStart
val numbers = listOf(5, 2, 10, 4)
val sumEven = numbers.foldIndexed(0) { idx, sum, element -> if (idx % 2 == 0) sum + element else sum }
println(sumEven)
val sumEvenRight = numbers.foldRightIndexed(0) { idx, element, sum -> if (idx % 2 == 0) sum + element else sum }
println(sumEvenRight)
//sampleEnd
}
All reduce operations throw an exception on empty collections. To receive null
instead, use their *OrNull()
counterparts: