We continue with more Scala on the topic of Pattern Matching in this post. For
all the work in this post, we will use Read-Evaluate-Print-Loop
Scala interpreter. Some familiarity
with Java will be of great help in understanding Scala. In this post, we will
look at the different ways Pattern Matching can be implemented in Scala.
We already saw a brief example in an earlier post that is replicated below:
val x = 1
x match {
case 1 => "One"
case 2 => "Two"
case _ => "Unknown"
}
The results are shown below:
scala> val x = 1
x: Int = 1
scala> x match {
|
| case 1 => "One"
|
| case 2 => "Two"
|
| case _ => "Unknown"
| }
res104: String = One
We can also match on the basis of types as shown below:
def TypeMatch(input: Any) = input match {
case i: Int => i.toBinaryString
case d: Double => d.toInt
}
TypeMatch(-5)
TypeMatch(-5.9)
The results are shown below:
scala> def TypeMatch(input: Any) = input match {
| case i: Int => i.toBinaryString
| case d: Double => d.toInt
| }
TypeMatch: (input: Any)Any
scala> TypeMatch(-5)
res105: Any = 11111111111111111111111111111011
scala> TypeMatch(-5.9)
res106: Any = -5
In the above example, the input is any object. If input is an integer, then, the input is converted into a binary string. If it is a Double, it is converted to an integer. Note that the case expressions, i and d are small case letters of the types that they describe.
Similar to above example, we can check for case classes as well as shown below:
case class Ferrari(Name: String, Type: String)
case class Ford(Name: String, Gas: String)
def CaseClassMatch(input: Any) = input match {
case Ferrari(name, _) => s"Ferrari called $name"
case Ford(name, gas) => s"Ford called $name, runs on $gas"
}
To test above code, we can use below code:
CaseClassMatch(Ferrari("California T","Automatic"))
CaseClassMatch(Ford("Endeavour","Diesel"))
The results are shown below:
scala> case class Ferrari(Name: String, Type: String)
defined class Ferrari
scala> case class Ford(Name: String, Gas: String)
defined class Ford
scala> def CaseClassMatch(input: Any) = input match {
| case Ferrari(name, _) => s"Ferrari called $name"
| case Ford(name, gas) => s"Ford called $name, runs on $gas"
| }
CaseClassMatch: (input: Any)String
scala> CaseClassMatch(Ferrari("California T","Automatic"))
res120: String = Ferrari called California T
scala> CaseClassMatch(Ford("Endeavour","Diesel"))
res121: String = Ford called Endeavour, runs on Diesel
We can add a if clause to make this pattern matching more specific as shown in below program:
def CaseClassMatchWithIf(input: Any) = input match {
case Ferrari(name, _) if (name == "California T") => s"Ferrari called $name"
case Ford(name, gas) if (gas == "Petrol") => s"Ford called $name, runs on $gas"
}
Then, we can test the above code with below commands:
CaseClassMatchWithIf(Ferrari("CaliforniaT","Automatic"))
CaseClassMatchWithIf(Ford("Endeavour","Petrol"))
CaseClassMatchWithIf(Ford("Endeavour","Diesel"))
The last command errors out as it fails the if test.
The results are shown below:
scala> def CaseClassMatchWithIf(input: Any) = input match {
| case Ferrari(name, _) if (name == "California T") => s"Ferrari called $name"
| case Ford(name, gas) if (gas == "Petrol") => s"Ford called $name, runs on $gas"
| }
CaseClassMatchWithIf: (input: Any)String
scala> CaseClassMatchWithIf(Ferrari("California T","Automatic"))
res146: String = Ferrari called California T
scala> CaseClassMatchWithIf(Ford("Endeavour","Petrol"))
res147: String = Ford called Endeavour, runs on Petrol
scala> CaseClassMatchWithIf(Ford("Endeavour","Diesel"))
scala.MatchError: Ford(Endeavour,Diesel) (of class Ford)
at .CaseClassMatchWithIf(<console>:16)
... 32 elided
This concludes the discussion on Pattern Matching in Scala.
We already saw a brief example in an earlier post that is replicated below:
val x = 1
x match {
case 1 => "One"
case 2 => "Two"
case _ => "Unknown"
}
The results are shown below:
scala> val x = 1
x: Int = 1
scala> x match {
|
| case 1 => "One"
|
| case 2 => "Two"
|
| case _ => "Unknown"
| }
res104: String = One
We can also match on the basis of types as shown below:
def TypeMatch(input: Any) = input match {
case i: Int => i.toBinaryString
case d: Double => d.toInt
}
TypeMatch(-5)
TypeMatch(-5.9)
The results are shown below:
scala> def TypeMatch(input: Any) = input match {
| case i: Int => i.toBinaryString
| case d: Double => d.toInt
| }
TypeMatch: (input: Any)Any
scala> TypeMatch(-5)
res105: Any = 11111111111111111111111111111011
scala> TypeMatch(-5.9)
res106: Any = -5
In the above example, the input is any object. If input is an integer, then, the input is converted into a binary string. If it is a Double, it is converted to an integer. Note that the case expressions, i and d are small case letters of the types that they describe.
Similar to above example, we can check for case classes as well as shown below:
case class Ferrari(Name: String, Type: String)
case class Ford(Name: String, Gas: String)
def CaseClassMatch(input: Any) = input match {
case Ferrari(name, _) => s"Ferrari called $name"
case Ford(name, gas) => s"Ford called $name, runs on $gas"
}
To test above code, we can use below code:
CaseClassMatch(Ferrari("California T","Automatic"))
CaseClassMatch(Ford("Endeavour","Diesel"))
The results are shown below:
scala> case class Ferrari(Name: String, Type: String)
defined class Ferrari
scala> case class Ford(Name: String, Gas: String)
defined class Ford
scala> def CaseClassMatch(input: Any) = input match {
| case Ferrari(name, _) => s"Ferrari called $name"
| case Ford(name, gas) => s"Ford called $name, runs on $gas"
| }
CaseClassMatch: (input: Any)String
scala> CaseClassMatch(Ferrari("California T","Automatic"))
res120: String = Ferrari called California T
scala> CaseClassMatch(Ford("Endeavour","Diesel"))
res121: String = Ford called Endeavour, runs on Diesel
We can add a if clause to make this pattern matching more specific as shown in below program:
def CaseClassMatchWithIf(input: Any) = input match {
case Ferrari(name, _) if (name == "California T") => s"Ferrari called $name"
case Ford(name, gas) if (gas == "Petrol") => s"Ford called $name, runs on $gas"
}
Then, we can test the above code with below commands:
CaseClassMatchWithIf(Ferrari("CaliforniaT","Automatic"))
CaseClassMatchWithIf(Ford("Endeavour","Petrol"))
CaseClassMatchWithIf(Ford("Endeavour","Diesel"))
The last command errors out as it fails the if test.
The results are shown below:
scala> def CaseClassMatchWithIf(input: Any) = input match {
| case Ferrari(name, _) if (name == "California T") => s"Ferrari called $name"
| case Ford(name, gas) if (gas == "Petrol") => s"Ford called $name, runs on $gas"
| }
CaseClassMatchWithIf: (input: Any)String
scala> CaseClassMatchWithIf(Ferrari("California T","Automatic"))
res146: String = Ferrari called California T
scala> CaseClassMatchWithIf(Ford("Endeavour","Petrol"))
res147: String = Ford called Endeavour, runs on Petrol
scala> CaseClassMatchWithIf(Ford("Endeavour","Diesel"))
scala.MatchError: Ford(Endeavour,Diesel) (of class Ford)
at .CaseClassMatchWithIf(<console>:16)
... 32 elided
This concludes the discussion on Pattern Matching in Scala.