Aleš Zrak
Aleš Zrak

Reputation: 683

Kotlin: conditional items during map creation

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

Answers (4)

Emanuel George Hategan
Emanuel George Hategan

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

Willi Mentzel
Willi Mentzel

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

Ben
Ben

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

hotkey
hotkey

Reputation: 148129

One way to do that is to use listOfNotNull(...) + .toMap() and put nulls 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

Related Questions