cool breeze
cool breeze

Reputation: 4811

Using filterNot with a Map

I have a simple map

val m = Map("a1" -> "1", "b2" -> "2", "c3" -> "3")
val someList = List("b", "d")
m.filterNot( (k,v) => someList.exist(l => k.startsWith(l)) )

I'm getting an error:

error: missing parameter type

I'm doing something silly here I'm sure, why isn' this compiling?

Upvotes: 1

Views: 3306

Answers (3)

elm
elm

Reputation: 20415

Using for comprehension syntax, extraction and filtering may be achieved as follows,

for ( pair@(k,v) <- m; l <- someList if !k.startsWith(l)) yield pair

Upvotes: 1

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

filterNot needs a case keyword and {} when you extract k, v from tuple.

note that its not exist its exists

m.filterNot { case (k,v) => someList.exists(l => k.startsWith(l)) }

or

m.filterNot(pair => someList.exists(l => pair._1.startsWith(l)))

Explanation

As you are extracting k, v from the tuple using extractor syntax you have to use case keyword and {}

Without extractor syntax you can do

m.filterNot(pair => someList.exists(l => pair._1.startsWith(l)))

Scala REPL

scala> val m = Map("a1" -> "1", "b2" -> "2", "c3" -> "3")
m: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, b2 -> 2, c3 -> 3)

scala> val someList = List("b", "d")
someList: List[String] = List(b, d)

scala>  m.filterNot { case (k,v) => someList.exists(l => k.startsWith(l)) }
res15: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, c3 -> 3)

Without extractor syntax

Now you need not use case keyword and {} as we are not using extracting the key and value using extractor syntax

scala> m.filterNot(pair => someList.exists(l => pair._1.startsWith(l)))
res18: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, c3 -> 3)

scala> val m = Map("a1" -> "1", "b2" -> "2", "c3" -> "3")
m: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, b2 -> 2, c3 -> 3)

scala> val someList = List("b", "d")
someList: List[String] = List(b, d)

scala> m.filterNot(pair => someList.exists(l => pair._1.startsWith(l)))
res19: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, c3 -> 3)

Upvotes: 4

stefanobaghino
stefanobaghino

Reputation: 12804

The issue is this: the filterNot method accepts one parameter, while you are defining a list of two parameters. This confuses the compiler and that message is the result.

In order to solve it, you can use the following syntax (notice the usage of pattern matching with the case keyword):

m.filterNot { case (k,v) => someList.exist(l => k.startsWith(l)) }

Using the pattern matching like this creates a PartialFunction that will be decompose key and value and be applied like a normal function to your Map.

Upvotes: 2

Related Questions