Practical Use Cases of Switch Statement in Scala

1. Catch blocks are Pattern Matches and is same as below code

    try {
        // logic
    } catch {
        case e: RuntimeException => "runtime"
        case e: NullPointerException => "npe"
        case _ => "something else"
    }

    // Catch blocks are Pattern Matches and is same as below code
    /*
    try {
        // logic
    } catch(e) {
    e match {
        case e: RuntimeException => "runtime"
        case e: NullPointerException => "npe"
        case _ => "something else"
        }
    }
     */

2. Generators are also based on pattern matching

val list = List(1, 2, 3, 4)
    val evenOnes = for {
        x <- list if x % 2 == 0 // GENERATOR
    } yield x
    println(evenOnes)

    val tuples = List((1, 2), (2, 3))
    val filterTuples = for {
        (first, second) <- tuples // extractor in this generator
    } yield first * second
    println(filterTuples)

3. Multi value definitons are based on PMs

val tuple = (1, 2, 3)
    val (a, b, c) = tuple
    println(b)

    val head :: tail = list
    println(head)
    println(tail)

4. Partial Functions are based on Pattern Matching

    val mappedList = list.map {
        case v if v % 2 == 0 => s"$v is even"
        case 1 => "One"
        case _ => "Something else "
    }
    println(mappedList)
    // Note: Partial Function is a literal inside {}

    // is same as
    val mappedList2 = list.map(x => x match {
        case v if v % 2 == 0 => s"$v is even"
        case 1 => "One"
        case _ => "Something else "
    })

Switch Cases and Pattern Matching in Scala

In scala switch is enabled via Pattern Matching (PM) and its much more powerful than other languages often referred as “Switch on Steroids”
Some of the properties of switch case are
1. Cases are match in the same order they are written
2. If no cases match it will result in MatchError, make sure all the cases are covered with wildcard
3. Type of Pattern Matching expression is the unified type of all the types from all the cases
4. PM works really well with case classes

Simple switch statement

val random = new Random
    val x = random.nextInt(10)

    val description = x match {
        case 1 => "First element"
        case 2 => "Second element"
        case 3 => "Third element"
        case _ => "Default element" // this is a WILDCARD which matches for all other patterns
    }
    println(description)

Interesting property of Pattern Matching is that it can decompose values especially when used with case classes.

sealed class Animal
case class Dog(breed: String) extends Animal
case class Parrot(greeting: String) extends Animal

val animal: Animal = Dog("terra Nova")
animal match {
    case Dog(breed) => println(s"Matched dog of type $breed breed")
}

Different scenarios/ways we can use switch statement

    // 1. Constants
    val x: Any = "Scala"

    val constants: Any = x match {
        case 1 => "a number"
        case "Scala" => "The scala"
        case true => "The Truth"
        case a02AllThePatterns => "A singleton Object"
     }
    println(constants)

    // 2. Match Anything
    // 2.1 Wildcard
    val matchAnything = x match {
        case _ => "I will match everything"
    }
    println(matchAnything)

    // 2.2 variable
    val matchAVariable = x match {
        case something => s"I have found $something"
    }
    println(matchAVariable)

    // 3 tuples
    val aTuple = (1, 2)
    val matchATuple = aTuple match {
        case (1, 1) => "Found tuple"
        case (something, 2) => s"I have found tuple with $something"
    }
    println(matchATuple)

    // PMs can be nested
    val nestedTuple = (1, (2, 3))
    val matchANestedTuple = nestedTuple match {
        case (_, (2, v)) =>
    }
    println(matchANestedTuple)

    // 4. case classes - constructor pattern
    // PMs can be nested with CCs as well
    val aList: GenericList[Int] = new Cons(1, new Cons(2, Empty))
    val matchAList = aList match {
        case Empty =>
        case Cons(h, t) =>
        case Cons(h, Cons(subHead, subTail)) =>  // nested classes
    }

    // 5 - List Patterns
    val aStandardList = List(1, 2, 3, 4, 5)
    val matchAStandardList = aStandardList match {
        case List(1, _, _, _) => // extractor concept in advanced training
        case List(1, _*) => // List of arbitrary length in advanced training
        case 1 :: List(_) => // infix pattern
        case List(1, 2, 3) :+ 42 => // infix pattern
    }

    // 6. Type specifiers
    val unknown: Any = 2
    val matchAUnknown = unknown match {
        case list: List[Int] => // explicit type specifier
        case _ =>
    }

    // 7. Name Binding
    val MatchANameBinding = aList match {
        case nonEmptyList @ Cons(_, _) => 
            // name binding allows us to use the name later
            // Its like variables but we can name entire pattern here and its very powerful
        case Cons(1, rest @ Cons(2, _)) => 
            // Name Binding is also possible in nested patterns
    }

    // 8. Multi Patterns
    val matchAMultiPattern = aList match {
        case Empty | Cons(0, _) => // Matches multiple patterns with pipe operator
    }

    // 9. if guards
    val matchASpecialElement = aList match {
        case Cons(specialElement, _) if specialElement % 2 == 0 => 
        // if guard on a variable
    }
Mawazo

Mostly technology with occasional sprinkling of other random thoughts

amintabar

Amir Amintabar's personal page

101 Books

Reading my way through Time Magazine's 100 Greatest Novels since 1923 (plus Ulysses)

Seek, Plunnge and more...

My words, my world...

ARRM Foundation

Do not wait for leaders; do it alone, person to person - Mother Teresa

Executive Management

An unexamined life is not worth living – Socrates

javaproffesionals

A topnotch WordPress.com site

thehandwritinganalyst

Just another WordPress.com site

coding algorithms

"An approximate answer to the right problem is worth a good deal more than an exact answer to an approximate problem." -- John Tukey