Saurabh
Saurabh

Reputation: 73609

How to remove multiple keys from a Map dynamically

Say I have a map like this:

scala> val a = Map("a"->2, "d" -> 4, "r" -> 5)
a: scala.collection.immutable.Map[String,Int] = Map(a -> 2, d -> 4, r -> 5)

I want to remove multiple keys dynamically from this. While I am able to do this:

scala> a - ("a","r")
res13: scala.collection.immutable.Map[String,Int] = Map(d -> 4)

But following fails:

scala> val keys = ("d","r")
as: (String, String) = (d,r)

scala> a - keys
<console>:15: error: type mismatch;
 found   : (String, String)
 required: String
       a - keys
           ^

While I understand this will be some casting issue, but I am not able to figure this simple thing out.

Edit

I also tried to make keys as array, as in earlier example it became a Tuple, but that also fails.

scala> val keys = Array("d","r")
as: Array[String] = Array(d, r)

scala> a - keys
<console>:15: error: type mismatch;
 found   : Array[String]
 required: String
       a - keys
           ^

Upvotes: 7

Views: 4513

Answers (4)

Xavier Guihot
Xavier Guihot

Reputation: 61666

Starting Scala 2.13, immutable Maps are provided with the removedAll method, as an alias of --:

// val map = Map("a" -> 2, "d" -> 4, "r" -> 5)
map.removedAll(Set("a", "r"))
// collection.immutable.Map[String,Int] = Map("d" -> 4)

def removedAll(keys: IterableOnce[K]): Map[K, V]

Upvotes: 0

Jeffrey Chung
Jeffrey Chung

Reputation: 19517

To remove multiple keys from a Map, use the -- method:

a -- Set("a", "r")

The following explains the type mismatch error.

The version of the - method on Map that you're calling takes three arguments: (1) the key of the first element to remove, (2) the key of the second element to remove, and (3) a varargs representating zero or more remaining elements to remove. (The other version of - takes a single key as the argument.)

a - ("a", "r")

The above code is not passing a tuple to the - method; it's passing two String arguments to the - method. In other words, the above is equivalent to:

a.-("a", "r")

However, the code below...

val keys = ("d", "r")
a - keys

...is trying to pass a tuple as an argument to the - method. It's equivalent to:

a.-(("d", "r"))

You get a type mismatch error when you try to pass a tuple to the - method, because the - method expects one or more Strings.

Upvotes: 11

jwvh
jwvh

Reputation: 51271

This is nice and concise.

scala> a - "a" - "r"
res0: scala.collection.immutable.Map[String,Int] = Map(d -> 4)

If you'd like to compose the list of keys before the removal.

val ks = Seq("d","r")
ks.foldLeft(a)(_ - _)  //res2: collection.immutable.Map[String,Int] = Map(a -> 2)

Upvotes: 2

Tanjin
Tanjin

Reputation: 2452

The - operator works on one key at a time according to the Map API. If you have a Array of keys as you've attempted - You can try a foldLeft:

val keys = Array("d","r")
scala> keys: Array[String] = Array(d, r)

keys.foldLeft(a)((map, keyToRemove) => map - keyToRemove)
scala> res0: scala.collection.immutable.Map[String,Int] = Map(a -> 2)

Upvotes: 0

Related Questions