Careeroza
Aggregating with reduce and fold
Built-in Aggregates
Example
data class Item(val name: String, val price: Int, val qty: Int)
fun main() {
val cart = listOf(Item("Shirt", 799, 2), Item("Jeans", 1499, 1), Item("Cap", 299, 3))
println("Sum of prices: ${cart.sumOf { it.price }}")
println("Cart total: ${cart.sumOf { it.price * it.qty }}")
println("Average price: ${cart.map { it.price }.average()}")
println("Costliest: ${cart.maxBy { it.price }.name}")
println("Cheapest: ${cart.minByOrNull { it.price }?.name}")
}Output
Sum of prices: 2597 Cart total: 3994 Average price: 865.6666666666666 Costliest: Jeans Cheapest: Cap
reduce vs fold
reduce starts with the first element and combines the rest into it. fold starts with an initial value you give, so it works on empty lists and the result can be a different type.
Example
fun main() {
val nums = listOf(2, 3, 4)
println(nums.reduce { acc, n -> acc * n }) // 24
println(nums.fold(10) { acc, n -> acc + n }) // 10 + 2 + 3 + 4
println(nums.fold("") { acc, n -> acc + "[$n]" }) // different result type
val transactions = listOf(+5000, -1200, -300, +800)
val balances = transactions.runningFold(0) { bal, t -> bal + t }
println(balances)
println(emptyList<Int>().fold(0) { a, b -> a + b }) // 0
// emptyList<Int>().reduce { a, b -> a + b } -> throws: Empty collection can't be reduced
}Output
24 19 [2][3][4] [0, 5000, 3800, 3500, 4300] 0