# Collection processing in Kotlin: Folding and reducing

This is a chapter from the book Functional Kotlin. You can find it on LeanPub or Amazon. It is also available as a course.

`fold`

is the most universal method in our collection processing toolbox. We use it rarely because Kotlin standard library has already provided most important aggregate operations for us, but if we are missing a method for a specific task, `fold`

is at our service.

Let's see it practice. `fold`

is a method that accumulates all elements into a single variable (called an "accumulator") using a defined operation. For instance, let's say that our collection contains the numbers from 1 to 4, our initial accumulator value is 0, and our operation is addition. So `fold`

will:

- add the first value 1 to the initial accumulator value 0,
- then it will add the result 1 to the next value 2,
- then it will add the result 3 to the next value 3,
- then it will add the result 6 to the next value 4,
- and the result is 10.

As you can see, `fold(0) { acc, i -> acc + i }`

calculates the sum of all the numbers.

Since you can specify the initial value, you can decide the result type. If your initial value is an empty string and your operation is addition, then the result will be a "1234" string.

`fold`

is very universal. Nearly all collection processing methods can be implemented using it.

On the other hand, thanks to the fact that the Kotlin standard library has so many collection processing functions, we rarely need to use `fold`

. Even the functions we presented before that calculate a sum and join elements into a string have dedicated methods.

There is currently no standard library method to calculate the product of all the numbers in a collection, so this is where `fold`

can be used. We might use it directly, or we might use it to implement the `product`

method ourselves.

If you want to reverse the order of accumulation (to start from the end of the collection), use

`foldRight`

.

In some situations, you might want to have not only the result of `fold`

accumulations but also all the intermediate values. For that, you can use the `runningFold`

method or its alias^{1} `scan`

.

`runningFold(init, oper).last()`

and`scan(init, oper).last()`

always give the same result as`fold(init, oper)`

.

`reduce`

`reduce`

is a very similar function to `fold`

: it also accumulates all elements using a defined transformation. The difference is that in `reduce`

we do not define the initial value, and so `reduce`

uses the first element as the initial value. There are two consequences of this fact:

- If a collection is empty,
`reduce`

throws an exception. If we are not certain that a collection has elements, we should use`reduceOrNull`

, which returns`null`

for an empty collection. - The result from
`reduce`

must be of the same type as its elements. `reduce`

is slightly faster than`fold`

because it has one operation less to do.

`list.reduce(oper)`

is a lot like`list.drop(1).fold(list[0], oper)`

.

In general, I prefer using `fold`

whenever there is a "zero" value because `fold`

does not face the risk of an empty collection and it is able to control the result type.

Just like for

`fold`

, there is`runningReduce`

and`reduceRight`

.

`sum`

I mentioned that there is already a function to calculate the sum of all the numbers in a collection, and its name is `sum`

. It is implemented for all the basic ways of representing numbers, like `Int`

, `Long`

, `Double`

, etc.

When you have a list of elements and you want to calculate the sum of one of their properties, you could first map the elements onto the values of these properties, but it is more efficient to use `sumOf`

, which extracts a countable value for each element and then sums these values.

In this chapter, by aliases we will mean functions with exactly the same meaning.