Is there any Scala trick to enable pattern matching against map keys? In other words, I'd like to have an extractor that beside the Map instance accepted also a key value that would mean I want this pattern to match only if the matchable value is an instance of Map and there is an entry with the given key in it and the value for this entry be subject to recursive pattern matching.
Something like this:
myMap match {
case MyMap("a")(a) => // do smth with value a
case MyMap("b")(MyMap("c")(c)) => // do smth with value c
}
Update:
I've found some way to approach closer to the goal, but it's still not perfect because it implies definition of synthetic key-value-holders:
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")
}
Similar question: Can extractors be customized with parameters in the body of a case statement (or anywhere else that an extractor would be used)?
Feature request: SI-5435
Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.
Pattern matching is a way of checking the given sequence of tokens for the presence of the specific pattern. It is the most widely used feature in Scala. It is a technique for checking a value against a pattern. It is similar to the switch statement of Java and C.
Case classes are Scala's way to allow pattern matching on objects without requiring a large amount of boilerplate. In the common case, all you need to do is add a single case keyword to each class that you want to be pattern matchable.
case _ => does not check for the type, so it would match anything (similar to default in Java). case _ : ByteType matches only an instance of ByteType . It is the same like case x : ByteType , just without binding the casted matched object to a name x .
Maybe you are looking for solution that you don't really need? Can't imagine extractors here. You can use PF if you want to match key-value pairs:
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)
}
Return type is Option[Unit] because we use collectFirst and println
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With