Home > other >  Why can't I use map on Kotlins Regex Result sequence
Why can't I use map on Kotlins Regex Result sequence

Time:10-29

I worked with Kotlin's Regex API to get occurences of some regular expression. I wanted to convert the finding directly into another object so I intuitively used map() on the result sequence.

I was very surprised that the map function is never called but forEach is working. This example should make it clear:

val regex = "a.".toRegex()
val txt = "abacad"

var counter = 0

regex.findAll(txt).forEach { counter   }
println(counter)                            // 3

regex.findAll(txt).map { counter   }
println(counter)                            // still 3 since map is not called

regex.findAll(txt).forEach { counter   }
println(counter)                            // 6

My question is why? Did I oversee it in the documentation?

(tested on Kotlin 1.5.30)

CodePudding user response:

findAll() returns a Sequence<MatchResult>. Operations on Sequence are classified either as intermediate or terminal. The documentation for the functions declares which type they are. map and onEach are intermediate. Their action is deferred until a terminal operation is made. forEach is terminal.

Manipulating a Sequence with map returns a new Sequence that will perform the mapping function only when it is actually iterated, such as by a call to forEach or using it in a for loop.

This is the purpose of Sequence, to defer mutating functional calls. It can reduce allocations of intermediate Lists, or in some cases avoid applying the mutations on every single item, such as if the terminal call in the chain is a find() call.

  • Related