Scala - The unapplySeq Method



This chapter takes you through the unapplySeq method in Scala programming. The unapplySeq method is part of pattern matching.You can extract sequences of values from objects using the unapplySeq method.

The unapplySeq() Method

The unapplySeq() method is used in pattern matching. It is used to extract a sequence of elements from an object. It is used to work with collections and where you need to match and deconstruct sequences.

The unapplySeq() method is a special extractor method. The object can be decomposed into a sequence of values.

Syntax

The syntax of the unapplySeq method is -

object Extractor {
   def unapplySeq(input: Type): Option[Seq[ElementType]] = {
      // method body
   }
}

Example

The following example shows a simple unapplySeq method in Scala programming -

object IntList {
   def unapplySeq(input: String): Option[Seq[Int]] = {
      if (input.nonEmpty) {
         try {
            Some(input.split(",").map(_.trim.toInt).toSeq)
         } catch {
            case _: NumberFormatException => None
         }
      } else {
         None
      }
   }
}

object Demo {
   def main(args: Array[String]): Unit = {
      val input = "1, 2, 3, 4, 5"
      input match {
         case IntList(a, b, c, d, e) => println(s"Extracted values: $a, $b, $c, $d, $e")
         case _ => println("No match")
      }
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

Extracted values: 1, 2, 3, 4, 5

In the example, the IntList object defines an unapplySeq method. It extracts sequence of integers from comma-separated string. Demo object uses this method in pattern matching to extract and print the values.

Using unapplySeq() with Case Classes

The unapplySeq method can also be used with case classes. So pattern matching on sequences contained within case class instances.

Syntax

The syntax of the unapplySeq method with case classes is -

case class Demo(elements: ElementType*)

object Demo {
   def unapplySeq(demo: Demo): Option[Seq[ElementType]] = {
      Some(demo.elements)
   }
}

Example

The following example shows using unapplySeq with a case class Scala -

case class Person(names: String*)

object Person {
   def unapplySeq(person: Person): Option[Seq[String]] = {
      Some(person.names)
   }
}

object Demo {
   def main(args: Array[String]): Unit = {
      val person = Person("John", "Doe", "Smith")
      person match {
         case Person(first, second, last) => println(s"First: $first, Second: $second, Last: $last")
         case _ => println("No match")
      }
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

First: John, Second: Doe, Last: Smith

In the example, the Person case class and its companion object define an unapplySeq method. This extracts sequence of names from Person instance. Demo object uses this method in pattern matching to extract and print the names.

Advanced unapplySeq Usage

The unapplySeq method can be combined with other extractors to perform more pattern matching and extraction.

Syntax

The syntax of the unapplySeq method is -

object Extractor {
   def unapplySeq(input: Type): Option[Seq[ElementType]] = {
      // method body
   }
}

object OtherExtractor {
   def unapply(input: Type): Option[AnotherType] = {
      // method body
   }
}

Example

The following example shows advanced usage of unapplySeq with nested extractors in Scala programming -

object CSV {
   def unapplySeq(input: String): Option[Seq[String]] = {
      if (input.nonEmpty) Some(input.split(",").map(_.trim).toSeq)
         else None
   }
}

object Length {
   def unapply(input: Seq[String]): Option[Int] = Some(input.length)
}

object Demo {
   def main(args: Array[String]): Unit = {
      val input = "Scala, Java, Python, C++"
      input match {
         case CSV(a, b, c, d @ _*) if Length.unapply(d).contains(2) =>
         println(s"Languages: $a, $b, $c, ${d.mkString(", ")}")
         case _ => println("No match")
      }
   }
}

Save the above program in Demo.scala. Use the following commands to compile and execute this program.

Command

> scalac Demo.scala
> scala Demo

Output

Languages: Scala, Java, Python, C++

In the example, CSV object defines unapplySeq() method. It extracts sequence of values from comma-separated string. The Length object defines unapply() method. It extracts length of sequence. The Demo object uses these methods in pattern matching to extract. It also print the values only if the extracted sequence has specific length.

The unapplySeq() Method Summary

  • The unapplySeq() method in Scala is used in pattern matching to extract sequence of elements from an object.
  • The unapplySeq() method can be used with custom objects, case classes, and in combination with other extractors for advanced pattern matching.
  • Using unapplySeq() enhances code flexibility, readability, and reusability.
Advertisements