How To Use Pattern Matching

Reading Time: 3 minutes

Overview

In this blog, we will show a functional feature of Scala which is pattern matching.

If you have used Java or .NET in the past, it may at first sight appear similar to switch statements. But, Scala’s pattern matching is a lot more powerful!

Different ways of Pattern Matching

1. Pattern matching – a very basic example

Suppose you want to test a variable called donutType. In the case that its value is Glazed Donut, you will print Very Tasty. On the other hand, if its value is Plain Donut, then you will print Tasty.


val donutType = "Glazed Donut"
donutType match {
  case "Glazed Donut" => println("Very tasty")
  case "Plain Donut" => println("Tasty")
}

You should see the following output when you run your Scala application in IntelliJ:


Very tasty

NOTE:

  • You should have noticed that unlike in Java or in .NET, there are no break statements!
  • I’m pretty sure that you must have seen your share of bugs which come from the fact that someone forgot to use the break clause. In Java or .NET, this would allow the logic to fall-through to the next case statement.
  • Another big thanks to Scala as the compiler is smart enough to prevent fall-through and hence there is no need to use a break clause.

2. Pattern matching and return the result

What if instead of simply printing the different taste level of a donut, you would like to store it in a variable.


val tasteLevel = donutType match {
  case "Glazed Donut" => "Very tasty"
  case "Plain Donut" => "Tasty"
}
println(s"Taste level of $donutType = $tasteLevel")

You should see the following output when you run your Scala application in IntelliJ:


Taste level of Glazed Donut = Very tasty

NOTE:

  • Notice that you did not have to use the return keyword as you would in say Java or .NET.
  • Instead, the last expression will be the one returned back to the caller. We will see more return types as we get to tutorials on functions.

3. Pattern matching using the wildcard operator

As you have learned in Step 1, there is no need to use any break clauses as there is no fall-through when using pattern matching. But, what if you needed to provide a default case?


println("\nStep 3: Pattern matching using the wildcard operator")
val tasteLevel2 = donutType match {
  case "Glazed Donut" => "Very tasty"
  case "Plain Donut" => "Tasty"
  case _ => "Tasty"
}
println(s"Taste level of $donutType = $tasteLevel2")

You should see the following output when you run your Scala application in IntelliJ:


Step 3: Pattern matching using the wildcard operator
Taste level of Glazed Donut = Very tasty

NOTE:

  • If you come from a pure Object Oriented programming background, using the wildcard operator will almost certainly feel unnatural.
  • Don’t worry, we will see more examples of the wildcard operator in upcoming tutorials!

4. Pattern matching with two or more items on the same condition

In our example, we are labelling Glazed Donut item as Very Tasty. What if a Strawberry Donut was also Very Tasty. This behavior seems similar to an OR expression and you can use the pipe |


val tasteLevel3 = donutType match {
  case "Glazed Donut" | "Strawberry Donut" => "Very tasty"
  case "Plain Donut" => "Tasty"
  case _ => "Tasty"
}
println(s"Taste level of $donutType = $tasteLevel3")

You should see the following output when you run your Scala application in IntelliJ:


Taste level of Glazed Donut = Very tasty

5. Pattern matching and using if expressions in the case clause

Similar to Step 4, you can simulate an OR clause by adding if in the case statements.


val tasteLevel4 = donutType match {
  case donut if (donut.contains("Glazed") || donut.contains("Strawberry")) => "Very tasty"
  case "Plain Donut"  => "Tasty"
  case _  => "Tasty"
}
println(s"Taste level of $donutType = $tasteLevel4")

You should see the following output when you run your Scala application in IntelliJ:


Taste level of Glazed Donut = Very tasty

6. Pattern matching by types

So far we have been with the value of some variable. What if you would like to pattern match on the type of the variable?

Let’s declare a variable explicitly to be of type Any to hold the price of one donut.The Scala compiler would infer that priceOfDonut to be of type Double.

Let’s use some example to prove it!


println("\nStep 6: Pattern matching by types")
val priceOfDonut: Any = 2.50
val priceType = priceOfDonut match {
  case price: Int => "Int"
  case price: Double => "Double"
  case price: Float => "Float"
  case price: String => "String"
  case price: Boolean => "Boolean"
  case price: Char => "Char"
  case price: Long => "Long"
}
println(s"Donut price type = $priceType")

You should see the following output when you run your Scala application in IntelliJ:


Step 6: Pattern matching by types
Donut price type = Double

NOTE:

  • If you come from Java or .NET, you can think of the Any type similar to the Object class.
  • In other words, Any is at the root of Scala’s type hierarchy.

Conclusion

In this blog, we discussed about basic pattern matching, return the result back to the caller , wildcard operator, two or more items in same condition, with if expression and with types.

Stay Tune for more blogs on scala features.

Scala Future

Written by 

Meenakshi Goyal is a Software Consultant and started her career in an environment and organization where her skills are challenged each day, resulting in ample learning and growth opportunities. Proficient in Scala, Akka, Akka HTTP , JAVA. Passionate about implementing and launching new projects. Ability to translate business requirements into technical solutions. Her hobbies are traveling and dancing.

Leave a Reply