https://kotlinlang.org logo
Title
f

Filip de Waard

10/22/2020, 12:26 PM
We’re getting a flow of rows from the database (through r2dbc) like this:
db.execute { ... }.asType<Foo>().fetch().flow()
Now we want to return a Map. Two ways of doing that are:
db.execute { ... }.asType<Foo>().fetch().flow().fold(mapOf()) { acc, it -> acc + (transform(it.bar) to it.baz) }
or:
db.execute { ... }.asType<Foo>().fetch().flow().map(transform(it.bar) to it.baz).toList().toMap()
Which is better and why?
j

Javier

10/22/2020, 12:35 PM
I prefer the last one, more readable
f

Filip de Waard

10/22/2020, 12:36 PM
is there a performance difference? e.g. due to
toList
?
e

ephemient

10/22/2020, 12:54 PM
the first one is creating a new Map with every item in the flow, so the second one should be preferable from a performance standpoint too
f

Filip de Waard

10/22/2020, 12:59 PM
thank you, @Javier and @ephemient!
e

ephemient

10/22/2020, 1:00 PM
if you want to define your own extension, you could
suspend fun <T, K, V> Flow<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V> = buildMap {
    collect {
        val (key, value) = transform(it)
        set(key, value)
    }
}

db.execute { ... }.asType<Foo>().fetch().flow().associate { transform(it.bar) to it.baz }
f

Filip de Waard

10/22/2020, 1:03 PM
that would be more readable if we use it often, but would it also be faster?
e

ephemient

10/22/2020, 1:05 PM
you can benchmark it yourself... but expect yes, it won't create an intermediate list
f

Filip de Waard

10/22/2020, 1:22 PM
thanks a lot!