Showing posts with label c3010| match and case. Show all posts
Showing posts with label c3010| match and case. Show all posts

Example : Pattern matching on Regex

scala> //PS:119

scala> //psn > a40 > a50

scala> val myList = Seq(
     |   "Marks in physics=88,",
     |   "Other marks : english=75, science=80"
     | )
myList: Seq[String] = List(Marks in physics=88,, Other marks : english=75, science=80)

scala> 

scala> //A regex is created using 'r' method

scala> val Regex1 = """.*physics=([^,]+),""".r
Regex1: scala.util.matching.Regex = .*physics=([^,]+),

scala> 

scala> for(element <- myList) {
     |   val result = element match {
     |     case Regex1(phy) => s"Physics mark =${phy}"
     |     case _  => s"Others : $element"
     |   }
     |   println(result)
     | }
Physics mark =88
Others : Other marks : english=75, science=80

Note : Regex related methods are available in scala.util.matching.Regex

Pattern matching an Argument List

scala> //PS:117

scala> //psn > a40 > a40

scala> //Argument List is pattern matched using 

scala> //<variable name> @ _*

scala> def CheckSequence(myData: Seq[Char]) = myData match {
     |   case Seq('a', 'b', otherVals @ _*) => true
     |   case _ => false
     | }
CheckSequence: (myData: Seq[Char])Boolean

scala> 

scala> val data1 = Seq('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h')
data1: Seq[Char] = List(a, b, c, d, e, f, g, h)

scala> println(s"Result -> ${CheckSequence(data1)}")
Result -> true

scala> 

scala> val data1 = Seq('m', 'n', 'o', 'p', 'q')
data1: Seq[Char] = List(m, n, o, p, q)

scala> println(s"Result -> ${CheckSequence(data1)}")
Result -> false

Example : Pattern Matching(Extraction) on Case Classes

scala> //PS:110, 119
scala> //psn > a40 > a60

scala> case class Marks(firstTerm:Int, secondTerm:Int)
defined class Marks

scala> case class Subject(name:String, marks:Marks)
defined class Subject

scala> val phy = Subject("physics", Marks(70, 80))
phy: Subject = Subject(physics,Marks(70,80))

scala> val eng = Subject("english", Marks(75, 85))
eng: Subject = Subject(english,Marks(75,85))

scala> val math = Subject("math", Marks(80, 90))
math: Subject = Subject(math,Marks(80,90))


scala> for { seq <- Seq(phy, eng, math) } {
     |     val result = seq match {
     |         // Note 1 : unapply() method is used for Extraction
     |         //          (whereas apply() is used for creating an Object)
     |         // Note 2 : unapply()(apart from apply()) is also another
     |         //          method that has been created by the Compiler
     |         //          as part of Companion Object
     |         case Subject("physics", Marks(70, _)) => s"Physics : $seq"
     |         case s @ Subject("english", m @ Marks(_, _)) =>
     |                         s"English mark : ${m}"
     |         case Subject(_, _) => s"Others : $seq"
     |     }
     |     println(result)
     | }
Physics : Subject(physics,Marks(70,80))
English mark : Marks(75,85)
Others : Subject(math,Marks(80,90))

Example : Pattern matching on Tuples, Using Guards on Case Clause

val subjects = Seq(
                    ("physics", "1stTerm", 85),
                    ("physics", "2ndTerm", 90),
                    ("math", "2ndTerm", 80),
                    ("english", "1stTerm", 82)
                   )
val token = "physics"
for (x <- subjects) {
    val result = x match {
        // A Case clause with Guard(ie if m == "1stTerm")
        case (`token`, m, n) if m=="1stTerm" => s"Physics 1st Term : $x"
        case (_, _, _) => s"Other Subjects : $x"
    }
    println(result)
}

Pattern Matching on Sequence

scala> //PS:104
//convertToStr() : Method that takes a type parameter to convert a Sequence to String
scala> def convertToStr[T](seq: Seq[T]):String = {
     |     seq match {
     |         // Note 1 : Although a Sequence has 'head' & 'tail' methods
     |         //          here 'head' & 'tail' are considered as variable names
     |         // Note 2 : '+:' is called as 'cons'(Construction) Operator
     |         case head +: tail => s"$head +: " + convertToStr(tail)
     |
     |         // Nil is a Special Object that represents an Empty Sequence
     |         case Nil => "Nil"
     |     }
     | }
convertToStr: [T](seq: Seq[T])String

scala>

scala> val seq1 = Seq('a', 'b', 'c')
seq1: Seq[Char] = List(a, b, c)

scala> val seq2 = Seq.empty[Char]
seq2: Seq[Char] = List()

scala> val ls1 = List('d', 'e', 'f')
ls1: List[Char] = List(d, e, f)

scala> val ls2 = List.empty[Char]
ls2: List[Char] = List()

scala>

scala> for (seq <- Seq(seq1, seq2, ls1, ls2)) {
     |     println(convertToStr(seq))
     | }
a +: b +: c +: Nil
Nil
d +: e +: f +: Nil
Nil

Patter Matching Values, Variables & Types

When using match case, specific matching should appear before general mapping. In case clause, a word that start with a lowercase letter is considered as a new Variable. A word that starts with an Uppercase letter is considered to be a Type
//#PS:101
//psn > a40 > a20
scala> val mylist = Seq(3, 4, 5, 5.5, "mystring", "2ndstring", 
     |               1.7, 'something, true) 
mylist: Seq[Any] = List(3, 4, 5, 5.5, mystring, 2ndstring, 1.7, 'something, true)

scala> val mydata = 4           
mydata: Int = 4

scala> for ( data <- mylist){
     |   val mystr = data match {
     |     case 3           => s"Matches Integer '3'"
     |     //External variables are referred with backtick(``).
     |     //***Note : Not using `backtick`(like case mydata) is like a 
     |     //          catch all option
     |     case `mydata`    => s"Matches mydata '4'"
     |     // A word that start with an Upper case(Int here...) is considered
     |     // to be a Type
     |     case Int | _:Boolean      
     |                      => s"Matches any Integer/Boolean : $data"
     |     case "mystring"  => s"Matches String 'mystring'"
     |     case _:String    => s"Matches any string : $data"
     |     // As no type is given, Any is inferred
     |     case _           => s"Matches others : $data"  
     |   }
     |   println(mystr)
     | }
Matches Integer '3'
Matches mydata '4'
Matches others : 5
Matches others : 5.5
Matches String 'mystring'
Matches any string : 2ndstring
Matches others : 1.7
Matches others : 'something
Matches any Integer/Boolean : true

Pattern Matching(Deconstructing) using 'match' and 'case'

scala> //PS:99

scala> //psn > a40 > a11

//--------------- Example 1
scala> val lst = Seq(true, false)
lst: Seq[Boolean] = List(true, false)

scala> for (element <- lst) {
     |   element match {
     |     case true => println("This is True")
     |     case false => println("This is False")
     |   }
     | }
This is True
This is False
//--------------- Example 2
scala> 

scala> val lst = Seq(true, false)
lst: Seq[Boolean] = List(true, false)

scala> for (element <- lst) {
     |   element match {
     |     case true => println("This is True")
     |   }
     | }
<console>:42: warning: match may not be exhaustive.
It would fail on the following input: false
                element match {
                ^
This is True
scala.MatchError: false (of class java.lang.Boolean)
 at $anonfun$1.apply(<console>:42)
 at $anonfun$1.apply(<console>:41)
 at scala.collection.immutable.List.foreach(List.scala:318)
 at .<init>(<console>:41)
 at .<clinit>(<console>)
 at .<init>(<console>:7)
 at .<clinit>(<console>)
 at $print(<console>)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734)
 at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983)
 at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573)
 at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604)
 at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568)
 at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:760)
 at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805)
 at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:778)
 at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805)
 at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:778)
 at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805)
 at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:778)
 at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805)
 at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:778)
 at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:805)
 at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:717)
 at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:581)
 at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:588)
 at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:591)
 at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:882)
 at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837)
 at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:837)
 at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
 at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:837)
 at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:83)
 at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
 at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
 at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)