Idiomatic fold on mutable map


#1

I’d like to fold into a mutable map in the same way as an immutable map but there seems to be a lack of a method that will both mutate the map and return it. Now, plus returns Map, even when called on a mutable map. What gives? Should plus return the exact same kind of collection on which it was called? It’s also a shame that += always return Unit but this seems to be constrained by Java’s API.

Ideally, the following idiomatic fold into an immutable map should not require an expression to return the map when switched to mutableMap.

someList.fold(mapOf()) { m, e ->
    m + (k(e) to v(e))
}

someList.fold(mutableMapOf()) { m, e ->
    // this returns Map and loses the correct type.
    // m + (k(e) to v(e))
    m += (k(e) to v(e))
    m // unfortunately required here
}

Would the recommended method be to fold over an immutable Map and then convert it?


#2

It seems like you’re looking for associateBy or associateByTo functions:

val someList = listOf("abc", "def", "gh")
fun k(e: String) = e.take(1)
fun v(e: String) = e.toUpperCase()
fun main() {
val result = 
//sampleStart
someList.associateByTo(mutableMapOf(), { e -> k(e) }, { e -> v(e) })
//sampleEnd
println(result)
}

#3

Thanks for the speedy reply. This might work in specific cases but, still, isn’t it problematic that plus loses the type when applied to a mutable map?