Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Map pattern matching

How to do pattern matching on a Map in Scala ?

A (non working) attempt includes,

Map("a"->1, "b"->2, "c"->3) match {
  case Map(a,b,_*) => a
}

which errs with

value Map is not a case class, nor does it have an unapply/unapplySeq member
              case Map(a,b,_*) => a

The error is indicative enough, yet how to enrich Map with an unapply method for pattern matching ?

Many Thanks

Update

Following @Paul's comment, a neater use case may be like this,

Map("a"->1, "b"->2, "c"->3) match {
  case Map("b"->2,_*) => "222"
}

namely, in this case, if map contains key b that maps onto value 2.

like image 603
elm Avatar asked Aug 07 '14 09:08

elm


2 Answers

Most easy way is tramsform Map to List:

Map("a"->1, "b"->2, "c"->3).to[List] match {
  case List(a,b,_*) => a
}
like image 114
Yuriy Avatar answered Oct 02 '22 04:10

Yuriy


An approach to enriching Map with an unapplySeq method for pattern matching includes this,

object MapExtractor {
  def unapplySeq[A <% Ordered[A], B <% Ordered[B]]
      (s: Map[A,B]): Option[Seq[(A,B)]] = Some(s.toSeq.sorted) 
}

where the sorting approach may be changed to any orderable (items comparable) logic. In this example,

Map("b"->2, "a"->1, "c"->3) match {
  case MapExtractor ( x, xs @ _* ) => println(s"x: $x") ; println(s"xs: $xs") 
}

delivers

x: (a,1)
xs: ArrayBuffer((b,2), (c,3))
like image 41
elm Avatar answered Oct 02 '22 04:10

elm