Kotlin is a fantastic language. Every day, I find a new function or method that makes programming in it a breeze. One of my go-to functions I keep reaching for recently is fold. You can think of fold
like a reduce
; however, reduce
starts with the first value in the list, whereas fold
starts with the given initial value and the first item in the list.
An example always helps. We have a list of sites for a business and want to calculate the total staff numbers plus the staff at head office. We can pass the head office staff numbers in as the initial value.
val sites = listOf(
Site("Site A", 150),
Site("Site B", 120),
Site("Site C", 80),
Site("Site D", 200)
)
val headOfficeStaff = 25
val totalStaff = sites.fold(headOfficeStaff) {
total, site -> total + site.staffCount
}
println(totalStaff) // 575
So, we have a good idea of how to use fold
now; however, it has some other interesting use cases. When dealing with the Result
value in Kotlin, fold
can provide some nice syntax sugar when unwrapping the values. Let's use another example.
We want to fetch the carbon footprint for a given account and year. Internally, the function calls a database to get all footprints for an account and returns a Result
. We can use fold to process this Result
.
fun calculateFootprint(account: String, year: Int): Double? {
return getYearlyFootprintsForAccount(account).fold(
onFailure = { error ->
println("Error fetching data: ${error.message}")
null
},
onSuccess = { yearlyFootprints ->
yearlyFootprints.find { it.year == year }?.carbon
}
)
}
Honestly, I love fold
. Not only can you use it for formatting and aggregating data, but it provides a very clean way of processing Result values.