与Scala Map条目匹配的模式

时间:2013-09-03 07:32:08

标签: scala pattern-matching extractor

是否有任何Scala技巧可以启用针对地图键的模式匹配?换句话说,我想在Map实例旁边有一个提取器也接受一个键值,这意味着只有当matchable值是Map的一个实例并且有一个带有给定键的条目时,我希望这个模式匹配在其中,此条目的值受递归模式匹配的影响。

这样的事情:

myMap match {
    case MyMap("a")(a) => // do smth with value a
    case MyMap("b")(MyMap("c")(c)) => // do smth with value c
}

更新

我找到了一些接近目标的方法,但它仍然不完美,因为它意味着合成键值持有者的定义:

case class MapKey[K](key: K) {
  def unapply(o: Any) = o match {
    case m: Map[K, _] ⇒ m.get(key)
    case _ ⇒ None
  }
}

val m1 = Map("a" → "aa", "b" → Map("c" → "cc"))
val m2 = Map("a" → "aa", "d" → "dd")

val b = MapKey("b")
val c = MapKey("c")
val d = MapKey("d")

for (m ← List(m1, m2)) m match {
  case b(c(x)) ⇒ println(s"b > c: $x")
  case d(x) ⇒ println(s"d: $x")
}

类似的问题:Can extractors be customized with parameters in the body of a case statement (or anywhere else that an extractor would be used)?

功能请求:SI-5435

1 个答案:

答案 0 :(得分:1)

也许您正在寻找您不需要的解决方案?无法想象这里的提取器。如果要匹配键值对,可以使用PF:

val map = Map[String, String]("a" -> "b")

def matchTuple[A,B,C](map: Map[A,B])(pf: PartialFunction[(A,B), C]) = 
  map.collectFirst(pf)

matchTuple(map) {
  case ("a", b) => println("value for a is " + b)
}

返回类型是Option [Unit],因为我们使用collectFirst和println