One of the most well known higher-order functions on collections is map().
Let's say you have a function that receives a list of strings and returns a new list of the same size containing each string concatenated to itself:
val letters = listOf("a", "b", "c", "d")
println(repeatAll(letters)) // [aa, bb, cc, dd]
The task is quite trivial:
fun repeatAll(letters: List<String>): MutableList<String> {
val repeatedLetters = mutableListOf<String>()
for (l in letters) {
repeatedLetters.add(l + l)
}
return repeatedLetters
}
But for such a trivial task, we had to write quite a lot of code. What would we have to change in order to capitalize each string instead of repeating it twice? We would like to change only this line:
repeatedLetters.add(l + l) ----> repeatedLetters.add(l.toUpperCase())
But we have to create another function for that.
Of course, in Kotlin, we could pass a function as a second parameter. And since we don't actually care what the type is, as long as it's the same for both input and output, we can use generics:
fun <T> repeatSomething(input: List<T>, action: (T) -> T): MutableList<T> {
val result = mutableListOf<T>()
for (i in input) {
result.add(action(i))
}
return result
}
Now we can call our generified function as follows:
println(repeatSomething(letters) {
it.toUpperCase()
})
And that's almost exactly what .map() does:
println(letters.map {
it.toUpperCase()
})
Another variation of map() is mapTo().
In addition to the lambda, it receives the destination where the results should be incorporated.
You could do the following:
val letters = listOf("a", "B", "c", "D")
val results = mutableListOf<String>()
results.addAll(letters.map {
it.toUpperCase()
})
results.addAll(letters.map {
it.toLowerCase()
})
println(results)
But mapTo() lets you do this:
val letters = listOf("a", "B", "c", "D")
val results = mutableListOf<String>()
letters.mapTo(results) {
it.toUpperCase()
}
letters.mapTo(results) {
it.toLowerCase()
}
println(results)
In the second option, we use the results list as an argument, which allows us to reduce code nesting.