I am trying to filter a map from strings to ints in scala and I am running into a weird issue.
If I put the following into REPL:
scala> val myMap = Map("a" -> 1, "b" -> 2, "c" -> 3)
myMap: scala.collection.immutable.Map[java.lang.String,Int] =
| Map(a -> 1, b -> 2, c -> 3)
It's ok so far, and this works...
scala> myMap.filter(_._2 > 1)
res9: scala.collection.immutable.Map[java.lang.String,Int] = Map(b -> 2, c -> 3)
but this fails...
scala> myMap.filter((k:java.lang.String, v:Int) => v > 1)
<console>:9: error: type mismatch;
found : (java.lang.String, Int) => Boolean
required: ((java.lang.String, Int)) => Boolean
myMap.filter((k:java.lang.String, v:Int) => v > 1)
My question is what is going on with the error message and the extra pair of parentheses? If I try putting in an extra set of parentheses I get error: not a legal formal parameter.
filter
accepts a function that accepts only one parameter. In your expression, the expression accepts two parameters. However, the element happen to be a pair, so you may think you can give two parameters. The correct way of putting it would be something like:
myMap.filter (p => p._2 > 1)
That is, I receive a pair, p
, and its second element must be greater than 1.
myMap.filter
expects a function of type Tuple2[String, Int] => Boolean
, which is equivalent to ((String, Int)) => Boolean
. You're passing it a function of type (String, Int) => Boolean
; that is, a function that takes two arguments rather than a single Tuple2
.
Two ways to get it to work:
myMap.filter { case (k, v) => v > 1 }
and
myMap.filter(Function.tupled((k, v) => v > 1))
The first works by pattern matching, and the second by converting the function (String, Int) => Boolean
to ((String, Int)) => Boolean
.
By the way, there has been discussion about unifying tuples and function argument lists. Maybe in a future version of Scala, all functions will take a single parameter (which might be a tuple).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With