为什么我的地图不能使用过滤器?

Joh*_*n S 4 collections dictionary types scala filter

当我尝试执行以下操作时,我在Scala中遇到奇怪的类型不匹配错误:

val m = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3)
val n = Map[String, Int]("c" -> 3, "d" -> 4, "e" -> 5)
n.filter((k: String, v: Int) => !m.contains(k))
<console>:10: error: type mismatch;
 found   : (String, Int) => Boolean
 required: (String, Int) => Boolean
              n.filter((k: String, v: Int) => !m.contains(k))
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?类型不匹配在这里没有意义.

Nic*_*ick 14

实际需要的类型是((String,Int)),即单个参数是a Pair[String,Int],但您的语法是传递两个单独的参数.您可以传入部分函数,​​它使用case关键字匹配对:

n.filter { case(k, v) => !m.contains(k) }
Run Code Online (Sandbox Code Playgroud)

这是一篇关于它的相关文章.

Luigi值得指出,这filterKeys是一种更适合在这里使用的方法.

  • 由于没有使用值,可以考虑:`n.filter {case(k,_)=>!m.contains(k)}` (3认同)

Lui*_*hys 9

无用的错误消息是Scala 2.9中的一个已知错误.

它应该说的是什么

 found   : (String, Int) => Boolean
 required: ((String, Int)) => Boolean
Run Code Online (Sandbox Code Playgroud)

即你所提供的Function2[String, Int, Boolean]filter需要Function1[(String, Int), Boolean].

您可以使用模式匹配来匹配Nick显示的元组,直接提供Tomasz显示的元组函数,或者您可以使用以下方法将您Function2转换Function1为元组tupled:

n.filter(((k: String, v: Int) => !m.contains(k)).tupled)
// or
n.filter(Function.tupled((k, v) => !m.contains(k)))
Run Code Online (Sandbox Code Playgroud)

但是你最好使用内置filterKeys方法:

n.filterKeys(!m.contains(_))
Run Code Online (Sandbox Code Playgroud)