

Scala: Extractors and Pattern Matching
source link: https://blog.knoldus.com/scala-extractors-and-pattern-matching/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Scala: Extractors and Pattern Matching
Reading Time: 3 minutes
An extractor in Scala is an object which has an unapply method as one of its members. Often, the extractor object also defines a method apply for building values, but this is not required. An apply method is like a constructor which takes arguments and creates an object, the unapply method takes an object and tries to give back the arguments. The unapply method reverses the construction procedure of the apply method. the unapply method always returns an Option type, it returns either Some[T] (if it could successfully extract the parameter from the given object) or None, which means that the parameters could not be extracted.
Let’s understand this with the help of an example. We have an object which has both apply and unapply method.
object FullName { def apply(firstname: String, lastname: String) = { firstname + " " + lastname } def unapply(fullName: String): Option[(String, String)] = { val splittedName = fullName.split(" ") if (splittedName.length == 2) Some(splittedName(0), splittedName(1)) else None } }
Here, FullName(“Ayush”, “Hooda”) i.e., FullName.apply(“Ayush”, “Hooda”) will produce an output “Ayush Hooda” and FullName.unapply(“Ayush Hooda”) will produce an output of type Option[(String, String)] i.e., Some((Ayush, Hooda)).
For now, we have covered and concluded on a part that apply method is used to construct an object an unapply method is used to take an object as an input and gives back the arguments.
Return-type of unapply method:
The return type of an unapply should be chosen as follows:
- If it is just a test, return a Boolean.
- If it returns a single sub-value of type T, return an
Option[T]
. - If you want to return several sub-values
T1,...,Tn
, group them in an optional tupleOption[(T1,...,Tn)]
.
Usage of Extractors:
- Pattern Matching:
Extractors can be utilized in Pattern Matching. While comparing the Object of an Extractor in Pattern Matching, the unapply method will be executed spontaneously.object Divisor { def apply(x: Double): Double = x / 5 def unapply(z: Double): Option[Double] = { if (z % 5 == 0) { Some(z / 5) } else { None } } } val divisor = Divisor(50) // divisor will be 10 divisor match { // unapply method is called here. case Divisor(div) => print("Divisor: " + div) case _ => print("Not able to extract properly!!!") }
Here, the divisor object created which holds the value Divisor(50). Now, when the match is being applied onto it, unapply method is being called internally and helps with the cause of pattern matching, i.e., in this very example we match it against Divisor(div) and _ deals with other cases.
Note: A Case class already has an Extractor in it so, it can be used with Pattern Matching. - Testing:
Extractors can be utilized for testing. In this, a Boolean type is returned. Let us understand this with the help of an example.case class ModuloCheck(num: Int) object ModuloCheck { def unapply(num: ModuloCheck): Boolean = { if(num.num % 5 == 0) { true } else { false } } } object Testing extends App { val num = 10 val moduloNum = ModuloCheck(num) ModuloCheck.unapply(moduloNum) match { case testValue if testValue => print(s"${moduloNum.num} is divisible by 5") case _ => print(s"${moduloNum.num} is not divisible by 5") } }
UnapplySeq:
Sometimes, the number of values to extract isn’t fixed and we would like to return an arbitrary number of values, depending on the input. For this use case, you can define extractors with an unapplySeq
method which returns an Option[Seq[T]]
.
Syntax: def unapplySeq(object: X): Option[Seq[T]].
Here, we have an object of type X and this method either returns None, when the object does not match or returns a Sequence of extracted values of type T, enclosed in class Some.
Let us understand this with the help of an example.
object SortedSequence { def unapplySeq(seqOfIntegers: Seq[Int]): Option[Seq[Int]] = { if(seqOfIntegers == seqOfIntegers.sortWith(_ < _)) { Option(seqOfIntegers) } else { None } } } object UnapplySeq extends App { val listOfIntegers = List(1, 2, 3, 4, 5) // Applying pattern matching listOfIntegers match { case SortedSequence(a,b,c,d,e) => print(List(a, c, e)) } }
Here, we have used the sortWith method of Seq and match case is being applied on Seq[Int] and we can easily pattern match for every member of this very sequence.
Conclusion:
So, to conclude we have seen how Extractors can be useful in pattern matching and testing. Similarly, there can be many more custom use cases of Extractors that you can explore out. We also had explored how we can use unapplySeq for an unknown number of values.
For full Scala tutorial, refer to my Github Repository
References:
Recommend
-
68
-
15
Bartosz Jarkowski August 26, 2021 14 minute read ...
-
4
Knolx: Extractors & Implicit conversions Reading Time: < 1 minuteIn this presentation, I have explained few feature...
-
6
Home Menu Rust actix-web Extractors...
-
4
How to use extractors in Scala ? Reading Time: 3 minutesThis blog will guide you through the basic understanding of extractors in Scala. An extractor is an object that has an...
-
3
Reading Time: 3 minutes Pattern matching is the process of checking whether a specific sequence of characters/tokens/data exists among the given data. In Scala Pattern Matching is one of the most powerful feature which is basically s...
-
9
Authorizers, Extractors, and Policy objects Recently I was working on a Rails 4 project, and much to my surprise, my favorite authorization framework is not supported! CanCan had long been...
-
36
Extraction of SAP IBP Timeseries data from SAP S/4 HANA using extractors The SAP standard process map for SAP IBP Timeseries based Integration, talks more about end to end integration process from SAP S/4HANA or ERP to IBP...
-
4
[Submitted on 26 Jan 2022] Linear Branching Programs and Directional Affine Extractors ...
-
8
JavaScript Weekly Issue 607 « Prev ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK