2012-03-03 106 views
4

我得到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)) 

我做错什么了吗?类型不匹配在这里没有意义。

回答

14

实际需要的类型是((String,Int)),即单个参数是Pair[String,Int],但是您的语法传递了两个单独的参数。你可以通过在部分功能,而不是,它使用case关键字相匹配的对:

n.filter { case(k, v) => !m.contains(k) } 

这里有一个Relevant article了。

Luigi值得道具指出filterKeys是一个更合适的方法在这里使用。

+3

由于未使用的值,可以考虑:'n.filter {情况下(K,_)=> m.contains(K) }' – 2012-03-03 14:11:18

+0

是的,那是完美的有效。 – Nick 2012-03-03 14:35:23

+0

完美,谢谢尼克! – 2012-03-03 14:56:07

4

试试这个:

n.filter(entry => !m.contains(entry._1)) 

哪里entry是包含(key, value)所以entry._1元组是一个关键。

9

无用的错误信息是Scala 2.9中的一个已知错误。

什么应该说是

found : (String, Int) => Boolean 
required: ((String, Int)) => Boolean 

即当filter需要Function1[(String, Int), Boolean]时,您提供了Function2[String, Int, Boolean]

您可以使用模式匹配来匹配元组尼克表示,直接提供一个元组功能托马斯表示,或者你可以把你Function2Function1考虑使用tupled方法的元组:

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

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

n.filterKeys(!m.contains(_)) 
+0

+1指出它是一个2.9的错误(只是注意到我在2.8中试过了,所以我得到了正确的错误信息),并提及'filterKeys'。 – Nick 2012-03-04 13:50:19

相关问题