How to properly zip (combine) the values of two nullables in Kotlin?
I wonder what would be an idiomatic approach in Kotlin to combine two optional (nullable) values.
A simple showcase would be
// or some other type that might be null
val x: Int? = "42".toIntOrNull()
val y: Int? = "123".toIntOrNull()
// make a Pair or null in case x and/or y are actually null
// Pair might be actually a meaningful domain-specific product type instead
val combined: Pair<Int, Int>? = ...
Obviously the classic imperative style approach would be to make some kind of an if-expression
if (x != null && y != null) x to y
else null
While this approach isn't per se bad, I prefer expression style functions (instead of blocks) which I obviously can't use here as I need to refer to x and y twice.
A really ugly alternative would be to create a nested ?.let statement:
val combined: Pair<Int, Int>? =
x?.let { fst -> y?.let { snd -> fst to snd } }
How would a generic implementation of this admittedly ugly function look like?
val combined: Pair<Int, Int>? = x.zipWith(y, ::Pair)
fun <T, U, R> T?.zipWith(other: U?, transform: (T, U) -> R): R?
= this?.let { fst -> other?.let { snd -> transform(fst, snd) } }
What inspired me for the name of the function was actually definition in Project Reactor's Mono, the Definition in MonadZip @ Hoogle and Kotlin's own zip extension for collections
This does not really improve the former implementation but at least hides its ugliness into a reusable small utility function. It also uses the concept of zipping two contents of a Box found in other libraries, data types and programming languages
Is there a better approach for nullability combinations? Any comments on my thought process would also be appreciated!
from Recent Questions - Stack Overflow https://ift.tt/3qUxikV
https://ift.tt/eA8V8J
Comments
Post a Comment