Idiomatic way to transform map in kotlin?
HashmapKotlinHashmap Problem Overview
In Scala, it's just the map
function. For example, if hashMap is a hashMap of strings, then you can do the following:
val result : HashMap[String,String] = hashMap.map(case(k,v) => (k -> v.toUpperCase))
In Kotlin, however, map
turns the map into a list. Is there an idiomatic way of doing the same thing in Kotlin?
Hashmap Solutions
Solution 1 - Hashmap
I don't think one person's opinion counts as idiomatic, but I'd probably use
// transform keys only (use same values)
hashMap.mapKeys { it.key.uppercase() }
// transform values only (use same key) - what you're after!
hashMap.mapValues { it.value.uppercase() }
// transform keys + values
hashMap.entries.associate { it.key.uppercase() to it.value.uppercase() }
Note: or toUpperCase()
prior to Kotlin 1.5.0
Solution 2 - Hashmap
The [toMap
][1] function seems to be designed for this:
hashMap.map { (key, value) ->
key.toLowerCase() to value.toUpperCase()
}.toMap()
It converts Iterable<Pair<K, V>>
to Map<K, V>
[1]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/to-map.html
Solution 3 - Hashmap
You could use the stdlib mapValues
function that others have suggested:
hashMap.mapValues { it.value.uppercase() }
or with destructuring
hashMap.mapValues { (_, value) -> value.uppercase() }
I believe this is the most idiomatic way.
Solution 4 - Hashmap
I found another variant. It seems to be more clear
val result = mapOf( *hashMap.map { it.key.toUpperCase() to it.value.toUpperCase() }.toTypedArray() )
It'll automatically infer the type of resulted map.
.toTypedArray()
is required to use splat(*)
operator.