This function in kotlin expects zero or more pairs of properties.
fun trackEvent(vararg properties: Pair<Any?, Any?>){
...
}
Usually it is called like this and works great
trackEvent(
"time" to timeStr,
"user" to user
)
where timeStr
and user
are nullable Strings
So far so good, but this requires us to manually pass in all the variables individually to the tracking function whereas it would be easier to just pass in an object. To solve this, I created a function that takes in a Kotlin class and outputs an array of Pair
objects
fun Any.toArrOfPairs(): Array<Pair<Any?, Any?>>
{
...
}
and wish to use it like this
trackEvent(
*source?.toArrOfPairs()
)
There's a compiler error; however:
It seems like kotlin is worried about the case where source
is null. Is there an elegant to tell it to call trackEvent
with an empty array in this case?
Similarly, if we combine approaches and call trackEvent
as below, is there a way to tell kotlin "if source
is null, just pass in the other arguments (in this case - the "time" pair)
trackEvent(
"time" to timeStr,
*source?.toArrOfPairs()
)
Make your helper function accept a nullable receiver and return an empty array for the null case:
fun Any?.toArrOfPairs(): Array<Pair<Any?, Any?>>
{
this ?: return emptyArray()
// Your original code ...
}
Then skip the null-safe call when using it, because it's no longer necessary:
trackEvent(*source.toArrOfPairs())
I'm not sure if I understand the last part of your question exactly. If you want to combine explicit arguments and an array, you can:
trackEvent(
"time" to timeStr,
*source.toArrOfPairs()
)
If you wanted to only use the explicit arguments if the source is null, you could use the Elvis operator, but it's a bit ugly because then you have to put the explicit arguments in an array:
trackEvent(
*(source?.toArrOfPairs() ?: arrayOf("time" to timeStr))
)
Or just use an if statement. Maybe more verbose, but easier to read:
if (source != null) {
trackEvent(*source.toArrOfPairs())
} else {
trackEvent(
"time" to timeStr
)
}