# Pattern Matching

When we want to perform different computations based on some match or condition then we use pattern matching.

If you are familiar with switch statements, then this is similar to that but is a little more powerful.

There are different types of pattern matching techniques:

1. Wildcard Pattern

Wildcard pattern is referred to as the condition which is executed if all else fails. This is usually marked using “_” (underscore symbol).

``````val list = List("One", "Two", "Three")

list match {

case Nil => "Star Pattern"

case _ => "Wild card Pattern"

}``````

Output:

``````val list: List[String] = List(One, Two, Three)

val res0: String = Wild card Pattern``````

2. Variable Pattern

``````val message = "Hello ! What's up "

message match {
case greet: String => s"\$greet TGB Users"
}``````

Output:

``````val message: String = "Hello ! What's up "

val res1: String = Hello ! What's up  TGB Users``````

3. Constant Pattern

``````val ONE: Int = 1
val TWO: Int = 2
val THREE: Int = 3

def matcher(x: Int) {
x match {
case ONE => println("one")
case TWO => println("two")
case THREE => println("three")
case _ => println("many : Match case for Wildcard Pattern")
}
}

matcher(ONE)
matcher(TWO)``````

Output:

``````val ONE: Int = 1
val TWO: Int = 2
val THREE: Int = 3

def matcher(x: Int): Unit
one
two``````

4. Constructor Pattern

``````case class Pet(name: String, animal: String)

val listOfPets = List(Pet("Ginger", "Dog"),
Pet("boo", "Cat"),
Pet("Tommy", "Dog"),
Pet("Bow", "Dog"))

listOfPets.map {
case Pet(name, "Dog") => s"\$name is a Dog"
case _ => "The pet is not a Dog :)"
}``````

Output:

``````class Person

class Pet

val listOfPets: List[Pet] = List(Pet(Ginger,Dog), Pet(boo,Cat), Pet(Tommy,Dog), Pet(Bow,Dog))

val res4: List[String] = List(Ginger is a Dog, The pet is not a Dog :), Tommy is a Dog, Bow is a Dog)``````

5. Sequence Pattern

``````def getListType(x: List[Any]) = {

x match {
case Nil => "Got an Empty List"
case List(10, _, _) => "Got a size three list, starting with 10"
case List(1, _*) => "Got a list starting with one"
case _ => "Fallen in default case"
}
}

getListType(List())
getListType(List(1, 2, 3))
getListType(List(10, 2, 0))
getListType(List(3, 4, 7, 1))``````

Output:

``````def getListType(x: List[Any]): String

val res5: String = Got an Empty List

val res6: String = Got a list starting with one

val res7: String = Got a size three list, starting with 10

val res8: String = Fallen in default case``````

6. Tuple Pattern

``````val zippedValue1 = ("Gaurav", 1, 25)

val zippedValue2 = ("Mohit", 1, "25")

def decode(details: Any) = {

details match {

case (name: String, sr: Int, age: Int) => s"\$name-------\$sr-------\$age"

case (name: String, sr: Int, age: String) => s"\$name--------\$sr"

}

}

decode(zippedValue1)

decode(zippedValue2)``````

Output:

``````val zippedValue1: (String, Int, Int) = (Gaurav,1,25)
val zippedValue2: (String, Int, String) = (Mohit,1,25)
def decode(details: Any): String
val res9: String = Gaurav-------1-------25
val res10: String = Mohit--------1``````

7. Typed Pattern

``````def returnWhatYouGet(valType: Any) = {

valType match {

case s: String => s"you gave me this string: \$s"

case i: Int => s"thanks for the int: \$i"

case f: Float => s"thanks for the float: \$f"

case a: Array[Int] => s"an array of int: \${ a.mkString(",") }"

case as: Array[String] => s"an array of strings: \${ as.mkString(",") }"

case d: Pet => s"dog: \${ d.name }"

case list: List[_] => s"thanks for the List: \$list"

case m: Map[_, _] => m.toString

}

}

returnWhatYouGet("Hi")

returnWhatYouGet(1)

Output:

``````def returnWhatYouGet(valType: Any): String

val res11: String = you gave me this string: Hi

val res12: String = thanks for the int: 1

val res13: String = dog: Ginger``````

8. Using Pattern Guard

``````abstract class Notification

case class Email(sender:String, title: String, body: String) extends Notification
case class SMS(caller: String, message: String) extends Notification

case Email(email, _, _) if importantPeopleInfo.contains(email) =>

"You got an email from special someone!"

case SMS(number, _) if importantPeopleInfo.contains(number) =>

"You got an SMS from special someone!"

case other => "Unknown Service"
// nothing special, delegate to our original showNotification function
}
}

val importantPeopleInfo = Seq("867-5309", "jenny@gmail.com")
val someSms = SMS("867-5309", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
val importantEmail = Email("jenny@gmail.com", "Drinks tonight?", "I'm free after 5!")
val importantSms = SMS("867-5309", "I'm here! Where are you?")

Output:

``````class Notification

class Email

class SMS

class VoiceRecording

val importantPeopleInfo: Seq[String] = List(867-5309, jenny@gmail.com)

val someSms: SMS = SMS(867-5309,Are you there?)

val someVoiceRecording: VoiceRecording = VoiceRecording(Tom,voicerecording.org/id/123)

val importantEmail: Email = Email(jenny@gmail.com,Drinks tonight?,I'm free after 5!)

val importantSms: SMS = SMS(867-5309,I'm here! Where are you?)

You got an SMS from special someone!

Unknown Service

You got an email from special someone!

You got an SMS from special someone!``````

9. Sealed Class pattern

``````sealed abstract class Furniture

case class Couch() extends Furniture

case class Chair() extends Furniture

def findPlaceToSit(piece: Furniture): String = piece match {

case a: Couch => "Lie on the couch"

case b: Chair => "Sit on the chair"

}``````

Output:

``````class Furniture
class Couch
class Chair

def findPlaceToSit(piece: Furniture): String``````