Scala Extractor Objects

An Extractor object is an object with an unapply method which takes an object and tries to give back its arguments.

As we all know that apply method of an Object takes arguments and creates an object and the unapply method will do the reverse.

Lets see this with an example.



object Customer {

  def apply(firstName: String, lastName: String) = firstName + "," + lastName

  def unapply(customerName: String): Option[String] = {
    val nameArray = customerName.split(",")
    if (nameArray.nonEmpty) nameArray.headOption else None
  }

  def main(args: Array[String]): Unit = {
    val customer = Customer("Balachandar", "Kuppusamy")

    customer match {
      case Customer(name) => println(s"FirstName is:$name")
      case _ => println("Could not extract Name")
    }
  }
}


In the above code, Customer is an object and the apply method takes first and last names and combine those names with a comma symbol and the unapply method takes the name and split it and then return the first name as an output.

Customer(“Balachandar”, “Kuppusamy”) is a shorthand for calling Customer.apply(“Balchandar”, “Kuppusamy”) and case Customer(name) is a shorthand for calling Customer.apply(name).

The output of the above program will look like below,


FirstName is:Balachandar


Advertisements

ScalaTest

ScalaTest is a testing tool in the Scala eco system. Using this, we can test Java and Scala code effectively. Its very easy to use and it follows Behavior Driven Development(BDD).

In this post, we are going to see the usage of ScalaTest with an example.

Refer the below Scala Object “Operation”. This object contains methods to perform various mathematical operation.

Operation

Now let’s write a test class with the ScalaTest tool. Refer below the list of steps to be done to write a test class.

1. Create a test class and extend FunSpec class.
2. Then use describe and it to structure the test class and write the necessary tests.

Refer below the sample test class to test all the methods of “Operation” object.

OperationSpec

When we run the above test, the Run screen will look like below,

RunScreen

 

 

 

 

Scala foldLeft and foldRight functions

In this post, I am going to give some examples which explain how to use foldLeft and foldRight functions.

def foldLeft[B](z: B)(op: (B, A) ⇒ B): B – Applies a binary operator to a start value and all elements of this sequence, going left to right.

def foldRight[B](z: B)(op: (A, B) ⇒ B): B – Applies a binary operator to all elements of this list and a start value, going right to left.

Assume that you have a list and you want to add/multiply all the elements. We can use foldLeft function to do that. The order of traversing a list is from left to right. We can specify the initial value as well. Refer the below example.


object ScalaEx {
  def main(args: Array[String]): Unit = {

    val list = List(10, 10, 5)
    val total = list.foldLeft(1) {
      _ * _
    }
    println(s"Total::$total")

    val names = List("name1", "name2", "name3")
    val allNames = names.foldLeft("")((x, y) => x + " " + y)
    println(s"allNames::$allNames")
  }

}

The output is given below,



Total::500
allNames:: name1 name2 name3

In the above example, we have used foldLeft to multiply the value of a list and then reduce it to a single value and join a list.

The foldRight works the same way but the order of traversing a list is from right to left. Refer the below example to know it.



object ScalaEx {
  def main(args: Array[String]): Unit = {

    val names = List("name1", "name2", "name3")
    val allNamesFR = names.foldRight("")( (elem, acc) => acc + " " + elem )
    println(s"allNames with foldRight::$allNamesFR")

    val allNamesFL = names.foldLeft("")( (acc, elem) => acc + " " + elem )
    println(s"allNames with foldLeft::$allNamesFL")

  }

}


The output is given below,


allNames with foldRight:: name3 name2 name1
allNames with foldLeft:: name1 name2 name3


Scala List

In this post, we are going to see how we can merge two lists, append/prepend an element to a list.

We have various functions available to play with Scala List.

1. ::: or ++ operator to join two lists.
2. :+ and +: operators are used for append/prepend a value to a list(This will return a new list instance)


object Scala {

  def main(args: Array[String]): Unit = {

    //With ::: operator
    val list1 = List(1, 2, 3)
    val list2 = List(4, 5, 6)

    val joinList1 = list1 ::: list2
    println("joinList1::" + joinList1)


    //With ++ operator
    val joinList2 = list1 ++ list2
    println("joinList2::" + joinList2)


    //To append a value to an existing list use :+
    val appendList = list2 :+ 7
    println("appendList::" + appendList)


    //To prepend a value to an existing list
    val prependList =  3 +: list2
    println("prependList::" + prependList)

  }

}


The output is given below,


joinList1::List(1, 2, 3, 4, 5, 6)
joinList2::List(1, 2, 3, 4, 5, 6)
appendList::List(4, 5, 6, 7)
prependList::List(3, 4, 5, 6)

Scala zip/unzip function

Zip function is used to aggregate the contents of two lists into a single list of pairs.

Consider that, we have two lists one contain the list of tasks and another contains list of person names. We want to create another list contains person and task pair. Let see how we can use zip function to do this.

Refer the below example,


object ScalaMain {

  def main(args: Array[String]): Unit = {

    val taskList = List("task1", "task2", "task3")
    val personList = List("Peter", "John", "Patrick")

    val personWithTaskList = personList zip taskList

    personWithTaskList.foreach {
      case (person, task) =>
        println(s"$task is assigned to $person")
    }
  }
}


The output is given below,


task1 is assigned to Peter
task2 is assigned to John
task3 is assigned to Patrick

Unzip function will work as reverse of zip. Refer the below code and its output.



    val unzippedList = personWithTaskList unzip

    println(s"list of persons:${unzippedList._1}")
    println(s"list of tasks:${unzippedList._2}")


Output:


list of persons:List(Peter, John, Patrick)
list of tasks:List(task1, task2, task3)

As the “zip” function creates a pair, it will omit all the unpaired elements. Refer the below example,


object ScalaMain {

  def main(args: Array[String]): Unit = {

    val taskList = List("task1", "task2", "task3")
    val personList = List("Peter", "John", "Patrick", "Joe")

    val personWithTaskList = personList zip taskList

    personWithTaskList.foreach {
      case (person, task) =>
        println(s"$task is assigned to $person")
    }
  }

}


The output of the above program is given below,


task1 is assigned to Peter
task2 is assigned to John
task3 is assigned to Patrick


Scala Implicit Function – How to use

In this post, we are going to see how to use Scala Implicit function.

Assume we have a case class “Employee” class which contains name, age, role and location fields and we have a list of Employee case class objects. Lets see how to use Implicit function to find out the employee details by age and also by location.



case class Employee(name: String, age: Int, role: String, location: String)

class EmployeeFunction(employees: List[Employee]) {

    def findEmployeesByRole(role: String): List[Employee] ={
        employees
          .filter(e  => e.role == role)
    }

    def findEmployeesByLocation(location: String): List[Employee] ={
        employees
            .filter(e  => e.location == location)
    }

}

object EmployeeFunction {
    implicit def employeeFunction(employees: List[Employee]):EmployeeFunction = new EmployeeFunction(employees)
}


In the above code, The “EmployeeFunction” contains an implicit function “employeeFunction” defined with “implicit” keyword. So the employee list is implicitly passed to this function.

Now, to use this function in other file, we have to import this function.
Here in the below code, we import the function and then create a list of employee objects and then call “findEmployeesByRole” and “findEmployeesByLocation” methods on it.

Even though the methods findEmployeesByRole” and “findEmployeesByLocation” are not available on the List, it will call the “EmployeeFunction” class methods because of the implicit function.



import EmployeeFunction.employeeFunction

object EmployeeMain {

    def main(args: Array[String]): Unit = {

        val employees = List(Employee(name = "name0", age = 34, role = "programmer", location = "USA"),
                             Employee(name = "name1", age = 34, role = "manager", location = "USA"),
                             Employee(name = "name2", age = 34, role = "analyst", location = "USA"),
                             Employee(name = "name3", age = 33, role = "manager", location = "Canada"),
                             Employee(name = "name4", age = 34, role = "tech lead", location = "India"),
                             Employee(name = "name5", age = 37, role = "manager", location = "India"))

        println("All USA employees are\n" + employees.findEmployeesByLocation("USA"))
        println("All managers are:\n"+employees.findEmployeesByRole("manager"))

    }

}


Refer below the output of the above program



All USA employees are
List(Employee(name0,34,programmer,USA), Employee(name1,34,manager,USA), Employee(name2,34,analyst,USA))
All managers are:
List(Employee(name1,34,manager,USA), Employee(name3,33,manager,Canada), Employee(name5,37,manager,India))


Scala Try

The Try type in scala represents a computation that may either result in an exception, or return a successfully computed value.

In this post, We see how we can use Try type with an example.

Assume that we have a list of string and want to convert each value into number and If the value is not valid, then we have to throw an exception. We also do not want to break the program when an exception has been thrown.

Refer the below example to know how we can do that with Try type.



import scala.util.{Failure, Try}

object ScalaTryCatchExample {

    def main(args: Array[String]): Unit = {

        val values = List("1", "2", "3", "test", "5")

        values.foreach(value => {

            val tryOption = Try(convertValuesAsNumber(value))
            tryOption match {
                case Failure(e) =>
                    println(s" $value is not valid number. Exception is $e")
                case _ =>
            }
            println("Number:" + tryOption.toOption)
        }
        )

    }

    def convertValuesAsNumber(value: String): Integer = {
        if (value == null || !value.matches("[0-9]")) {
            throw new IllegalArgumentException()
        }
        Integer.valueOf(value)
    }
}


In the above Scala Object, we have “convertValuesAsNumber” method which is used to convert a string value into a number and also it throws an exception when if the value is null and not a valid number.

Here we wrap the convertValuesAsNumber method call into Try type. So when an exception throws, it would not break the program immediately. Instead the failure object is returned. So we can use match to find out this and finally call toOption method to get the value. If any exception throws then it will return a ‘None’ option.

We can also re-write the above program like below,


import scala.util.{Failure, Try}

object ScalaTryCatchExample {

    def main(args: Array[String]): Unit = {

        val values = List("1", "2", "3", "test", "5")

        values.foreach(value => {

            val tryOption = Try(Integer.valueOf(value))
            tryOption match {
                case Failure(e) =>
                    println(s" $value is not valid number. Exception is $e")
                case _ =>
            }
            println("Number:" + tryOption.toOption)
        }
        )

    }
}


The output of the above example is given below


Number:Some(1)
Number:Some(2)
Number:Some(3)
 test is not valid number. Exception is java.lang.IllegalArgumentException
Number:None
Number:Some(5)