In this tutorial, I will show you some examples that use Kotlin fold and fold indexed methods to accumulate List
and Map
.
Related Posts:
– Kotlin List & Mutable List tutorial with examples
– Kotlin sum(), sumBy(), sumByDouble() and BigDecimal in List, Map example
– Kotlin groupBy(), groupingBy() example
Kotlin Fold methods
fold()
This function helps to accumulate value starting with initial
value, then apply operation
from left to right to current accumulator value and each element.
public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (acc: R, T) -> R): R {
var accumulator = initial
for (element in this) accumulator = operation(accumulator, element)
return accumulator
}
foldRight()
foldRight()
is the same as fold()
, but works from right to left.
Remember that the positions of input parameters for operation
are changed.
public inline fun <T, R> List<T>.foldRight(initial: R, operation: (T, acc: R) -> R): R {
var accumulator = initial
if (!isEmpty()) {
val iterator = listIterator(size)
while (iterator.hasPrevious()) {
accumulator = operation(iterator.previous(), accumulator)
}
}
return accumulator
}
foldIndexed()
This method is just like fold()
with its index in the original collection.
public inline fun <T, R> Iterable<T>.foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R {
var index = 0
var accumulator = initial
for (element in this) accumulator = operation(checkIndexOverflow(index++), accumulator, element)
return accumulator
}
foldRightIndexed()
foldRightIndexed()
works from right to left.
The positions of input parameters for operation
are different from foldIndexed()
method.
public inline fun <T, R> List<T>.foldRightIndexed(initial: R, operation: (index: Int, T, acc: R) -> R): R {
var accumulator = initial
if (!isEmpty()) {
val iterator = listIterator(size)
while (iterator.hasPrevious()) {
val index = iterator.previousIndex()
accumulator = operation(index, iterator.previous(), accumulator)
}
}
return accumulator
}
In the next sections, I will show you how to work with the methods above.
Practice
Create a Data class
Let’s define Product class as following code:
Product.kt
package com.bezkoder.kotlin.fold
data class Product(val name: String, val quantity: Int) {
}
List
The examples show you how to use Kotlin fold in simple List.
package com.bezkoder.kotlin.fold
fun main(args: Array<String>) {
println(listOf(1, 2, 3, 4, 5).fold(0) { total, item -> total + item })
// 15
println(listOf(1, 2, 3, 4, 5).foldRight(0) { item, total -> total + item })
// 15
println(listOf(1, 2, 3, 4, 5).fold(1) { mul, item -> mul * item })
// 120
println(listOf(1, 2, 3, 4, 5).foldRight(1) { item, mul -> mul * item })
// 120
println(listOf(0, 1, 2, 3, 4, 5)
.foldIndexed(0) { index, total, item -> if (index % 2 == 0) (total + item) else total })
// 6
println(listOf(0, 1, 2, 3, 4, 5)
.foldRightIndexed(0) { index, item, total -> if (index % 2 == 0) (total + item) else total })
// 6
}
For List of Objects, this is how we get total quantity of Product(name,quantity)
List using fold()
method:
package com.bezkoder.kotlin.fold
fun main(args: Array<String>) {
val productList = listOf(
Product("A", 100),
Product("B", 200),
Product("C", 300),
Product("D", 400),
Product("E", 500)
)
val quantity = productList.map { it.quantity }.fold(0, { total, item -> total + item })
println(quantity)
// 1500
}
Map
package com.bezkoder.kotlin.fold
fun main(args: Array<String>) {
val productMap = mapOf(
"a" to Product("A", 100),
"b" to Product("B", 200),
"c" to Product("C", 300),
"d" to Product("C", 400),
"e" to Product("C", 500)
)
val quantity = productMap.map { it.value.quantity }.fold(0, { total, item -> total + item })
println(quantity)
// 1500
}
Conclusion
Today we’re learned how to use Kotlin fold()
, foldRight()
, foldIndexed()
, foldRightIndexed()
with some examples, from simple List to List of objects and Map.
Happly Learning! See you again.
Excellent Kotlin tutorial!
A very concise and well presented tutorial. Thank you. Mike
Like!! Thank you for publishing this awesome Kotlin tutorial.