Reputation: 683
Is there a way to do something like this in Kotlin?
mapOf(
"key1" to var1,
"key2" to var2,
if(var3 > 5) "key3" to var3
)
Or the only way is to add the key "key3" after the map is created? I'd like to add an item to a map only if some condition is met.
Upvotes: 28
Views: 21279
Reputation: 1263
I used to do the following for conditionally building the map:
mutableMapOf(
"key1" to val1,
"key2" to val2,
"key3" to val3
).also {
if (condition1) {
it["key4"] = val4
}
}.also {
if (condition2) {
it["key5"] = val5
}
}.toMap()
Sine multiple .also
method calls are allowed, you can split the customization logically enhancing readability.
Upvotes: 0
Reputation: 29884
Update: Kotlin 1.6 introduced a map builder (buildMap
). You can use it like this:
val map = buildMap<Char, Int>() {
put('a', 1)
put('b', 2)
if(var3 > 5) { put('c', 3) }
}
You can use the spread operator *
to do that:
val map = mapOf(
"key1" to var1,
"key2" to var2,
*(if(var3 > 5) arrayOf("key3" to var3) else arrayOf())
)
Upvotes: 27
Reputation: 1286
I like to use a "builder"
val map = let {
val m = HashMap<String, Int>() //use a mutable map as a map builder
m["key1"] = var1
m["key2"] = var2
if(var3 > 5){ m["key3"] = var3 }
m.toMap()
} //wrapped in a lambda so the builder is inside a private scope and can't accidentally be used
Upvotes: -1
Reputation: 148129
One way to do that is to use listOfNotNull(...)
+ .toMap()
and put null
s where you want to skip an item:
val map = listOfNotNull(
"key1" to var1,
"key2" to var2,
if (var3 > 5) "key3" to var3 else null
).toMap()
You can additionally use .takeIf { ... }
, but note that it will evaluate the pair regardless of the condition, so if the pair expression calls a function, it will be called anyway:
val map = listOfNotNull(
/* ... */
("key3" to var3).takeIf { var3 > 5 }
).toMap()
Upvotes: 48