kotlin-fold-example-feature-image

Kotlin Fold Example – Accumulate List using fold(), foldRight(), foldIndexed(), foldRightIndexed()

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.

Further Reading

2 thoughts to “Kotlin Fold Example – Accumulate List using fold(), foldRight(), foldIndexed(), foldRightIndexed()”

  1. Pingback: kevin

Leave a Reply

Your email address will not be published. Required fields are marked *