Match list items by type

I have a code similar to the one below:

def walkTree(list:List[Command]) { list match { case Command1::rest => doSomething(); walkTree(rest) case Command2::rest => doSomethingElse(); walkTree(rest) case Nil => ; } } 

I also know that you can map a pattern to a specific type and assign a variable at the same time:

 try { ... } catch { case ioExc:IOException => ioExc.printStackTrace() case exc:Exception => throw new RuntimeException("Oh Noes", e); } 

Is there a way to combine both types:

 def walkTree(list:List[Command]) { list match { case cmd1:Command1::rest => doSomething(); walkTree(rest) case cmd2:Command2::rest => doSomethingElse(); walkTree(rest) case Nil => ; } } 

Or do I need to extract each list item before matching?

+8
list scala pattern-matching
source share
2 answers

Yes, just use parentheses (see example below):

 def walkTree(list:List[Command]) { list match { case (cmd1:Command1)::rest => doSomething(); walkTree(rest) case (cmd2:Command2)::rest => doSomethingElse(); walkTree(rest) case Nil => ; } } 

However, you cannot use foreach to do this:

 scala> List(A(1), B(2), A(3), B(4), A(5)).foreach(_ match { | case (a:A) => println("a:" + a) | case (b:B) => println("b:" + b) | }) a:A(1) b:B(2) a:A(3) b:B(4) a:A(5) 

Example:

 scala> case class A(val i: Int); defined class A scala> case class B(val i: Int); defined class B scala> def walkTree(list: List[ScalaObject]) { | list match { | case (a:A)::rest => println("a:" + a); walkTree(rest); | case (b:B)::rest => println("b:" + b); walkTree(rest); | case Nil => ; | } | } walkTree: (list: List[ScalaObject])Unit scala> walkTree(List(A(1), B(2), A(3), B(4), A(5))) a:A(1) b:B(2) a:A(3) b:B(4) a:A(5) 
+18
source share

Using foreach and then pattern matching for each element seems to me more clear:

 def walkTree(list:List[Command]) { list foreach { _ match { case cmd1:Command1 => doSomething() case cmd2:Command2 => doSomethingElse() case _ => } } } 
+4
source share

All Articles