【问题标题】:Why can I not use a filter for my Map?为什么我的地图不能使用过滤器?
【发布时间】:2012-03-21 17:49:55
【问题描述】:

当我尝试执行以下操作时,我在 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))

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

【问题讨论】:

    标签: scala dictionary collections types filter


    【解决方案1】:

    实际需要的类型是((String,Int)),即单个参数是Pair[String,Int],但您的语法是传递两个单独的参数。您可以改为传入一个偏函数,它使用 case 关键字来匹配该对:

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

    这是一个关于它的Relevant article

    Luigi 值得支持指出 filterKeys 是在这里使用的更合适的方法。

    【讨论】:

    • 由于没有使用值,可以考虑:n.filter{case(k, _) =&gt; !m.contains(k) }
    【解决方案2】:

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

    应该说的是

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

    即当filter 需要Function1[(String, Int), Boolean] 时,您提供了Function2[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)))
    

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

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

    【讨论】:

    • +1 指出它是 2.9 的错误(只是注意到我在 2.8 中尝试过,所以我得到了正确的错误消息),并提到了 filterKeys
    【解决方案3】:

    试试这个:

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

    其中entry 是一个包含(key, value) 的元组,所以entry._1 是一个键。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-21
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多