我正在尝试在scala中将字符串从字符串过滤到int,我遇到了一个奇怪的问题。
如果我将以下内容放入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)
到目前为止还可以,这有效......
scala> myMap.filter(_._2 > 1)
res9: scala.collection.immutable.Map[java.lang.String,Int] = Map(b -> 2, c -> 3)
但这失败了......
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)
我的问题是错误消息和额外的一对括号是怎么回事?如果我尝试添加一组额外的括号,我会收到错误:不是合法的形式参数。
答案 0 :(得分:16)
myMap.filter
需要Tuple2[String, Int] => Boolean
类型的函数,该函数相当于((String, Int)) => Boolean
。你传递的是(String, Int) => Boolean
类型的函数;也就是说,一个带有两个参数而不是一个Tuple2
的函数。
让它发挥作用的两种方法:
myMap.filter { case (k, v) => v > 1 }
和
myMap.filter(Function.tupled((k, v) => v > 1))
第一个通过模式匹配工作,第二个通过将函数(String, Int) => Boolean
转换为((String, Int)) => Boolean
。
顺便说一下,有关统一元组和函数参数列表的讨论。也许在Scala的未来版本中,所有函数都将采用单个参数(可能是一个元组)。
答案 1 :(得分:6)
filter
接受只接受一个参数的函数。在表达式中,表达式接受两个参数。但是,元素碰巧是一对,所以你可能认为你可以给出两个参数。放置它的正确方法是:
myMap.filter (p => p._2 > 1)
也就是说,我收到一对p
,其第二个元素必须大于1.