Home > Net >  How should Kotlins Map.minus be used?
How should Kotlins Map.minus be used?

Time:11-16

How does Kotlins Map.minus work? I would have expected that the entries with the same key are removed.

fun main() 
{
    val left = mapOf(1 to "first", 2 to "second")
    val right = mapOf(1 to "first")
    val diff = left.minus(right)
    
    println(left)
    println(right)
    println(diff)  
}
Output: 
{1=first, 2=second}
{1=first}
{1=first, 2=second}

Expected: 
{1=first, 2=second}
{1=first}
{2=second}

From the Kotlin documentation:

Returns a map containing all entries of the original map except the entry with the given key. The returned map preserves the entry iteration order of the original map.

CodePudding user response:

The parameter of minus is K, not another map:

operator fun <K, V> Map<out K, V>.minus(key: K): Map<K, V>

So you should do:

val diff = left.minus(1)
// or
val diff = left - 1

Passing in a Map also compiles (but does not do what you expect) because minus's receiver is a map with a covariant (out) key type. The compiler simply treats your left map as a Map<Any, String>, and tries to remove the key mapOf(1 to "first") from it. Of course, your map does not have another map as a key, so nothing is removed. Notice that the diff produced this way is of type Map<Any, String>.

Note that the documentation also says "the given key", not "the keys in the given map", so you are supposed to give a key here.

If you want to remove multiple keys, you can give it an Iterable, Array, or Sequence of keys (not maps!). This will call the other overloads of minus.

val diff = left - right.keys
  • Related