Switch statements on steroids: Scala pattern matching

Scala provides a powerful pattern matching feature. Pattern matching enables us to match on much more than just ordinal values. It can be thought of as a switch statement on steriods. This post only scratches the surface of what can be done with pattern matching in Scala, but should provide you with a taste of what’s possible.

Matching based on types

The first example demonstrates how Scala can match based on type. Object of different types are fed into the match expression. Note how objects can be identified based on their type (in this case Int, String, Map):

    //match by type
    for (item <- List(66, "StringsAreGreat", Map.empty[Int, String], 22f)) {
      item match {
        case n: Int => println("Integers are awesome!")
        case str: String => println("Strings are the best")
        case m: Map[Int, String] => println("Ooh a map! buried treasure?")
        case _ => println("Something unexpected")
      }
    }
	

Matching on regular expressions

Matching with regular expressions enables you to find not only Strings which match the regex, but also provides access to group matches. Note how (_,_,octet3,_) maps onto the four IP address octets in the regex. We use ‘_’ as we only care about the actual value of the third octet :

    //match with regex
    val Ipv4Addr = """(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})""".r //yes there are better regexes for this
    val TwentiethCentury = """MCM.*""".r
    for (str <- List("172.99.6.4", "MCMXV", "woof")) {
      str match {
        case Ipv4Addr(_, _, octet3, _) => println ("Found an IPv4 address with a third octet of "+octet3)
        case TwentiethCentury() => println("Received a date in the twentieth century as Roman numerals")
        case _ => println("Your input doesn't match any of our patterns")
      }
    }
    

Wildcard matching with case classes

One of the most powerful ways to use pattern matching in Scala is to use case classes. Case classes enable matching based on selected attributes of objects. Note how we can filter for objects with certain attributes, using ‘_’ for cases where we don’t care what a value is:

    case class Person(name: String, hairColour: String,  age: Int)

    //matching with case classes
    for (item <- List(Person("Fred", "Brown", 44), Person("Jessica", "Blonde", 23), Person("Emma", "Blonde", 25))) {
      item match {
        case Person(_,"Brown",_) => println("A person with brown hair found. Welcome")
        case Person(name, "Blonde", 25) => println("25 year old blonde. Welcome "+name)
        case Person(name, hair, _) => println("An unexpected visitor with "+hair+" hair. Welcome "+name)
      }
    }
	

It should be clear, even from these short examples, that pattern matching allows for much more expressive code than using a traditional switch statement.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s