Learn How To Use Tuples (Pattern Match)
Overview
In this tutorial, we will show how to use the convenient Tuple classes to easily store elements as pairs. If you paid attention in your database class at school :) I'm pretty sure that you would have come across the word Tuple.
In Scala, you can think of tuples in terms of providing easy semantics for grouping your data points.
Steps
1. Using Tuple2 to store 2 data points
Let's continue using our donut examples from the previous tutorials. What if you would like to store the taste level of donuts along with the donut type? The Tuple2 class is your friend here :)
println("Step 1: Using Tuple2 to store 2 data points")
val glazedDonutTuple = Tuple2("Glazed Donut", "Very Tasty")
println(s"Glazed Donut with 2 data points = $glazedDonutTuple")
You should see the following output when you run your Scala application in IntelliJ:
Step 1: Using Tuple2 to store 2 data points
Glazed Donut with 2 data points = (Glazed Donut,Very Tasty)
2. Access each element in tuple
In Step 1, we've only printed the tuple glazedDonutTuple. What if you now would like to access each individual element.
println("\nStep 2: Access each element in tuple")
val donutType = glazedDonutTuple._1
val donutTasteLevel = glazedDonutTuple._2
println(s"$donutType taste level is $donutTasteLevel")
You should see the following output when you run your Scala application in IntelliJ:
Step 2: Access each element in tuple
Glazed Donut taste level is Very Tasty
3. Using TupleN classes to store more than 2 data points
Let's extend our examples from Step 1 and 2. What if you also wanted to store the price of the glazed donut?. You now have 3 data points namely the donut type, its taste level and then its price. Not to worry, Scala provides Tuple3 class to achieve just this!
println("\nStep 3: Using TupleN classes to store more than 2 data points")
val glazedDonut = Tuple3("Glazed Donut", "Very Tasty", 2.50)
println(s"${glazedDonut._1} taste level is ${glazedDonut._2} and it's price is ${glazedDonut._3}")
You should see the following output when you run your Scala application in IntelliJ:
Step 3: Using TupleN classes to store more than 2 data points
Glazed Donut taste level is Very Tasty and it's price is 2.5
4. How to use pattern matching on Tuples
In the previous tutorial, we've shown how to use pattern matching in Scala. Let's create two additional donut tuples one for storing the data points of Plain Donut and another one for Strawberry Donut.
println("\nStep 4: How to use pattern matching on Tuples")
val strawberryDonut = Tuple3("Strawberry Donut", "Very Tasty", 2.50)
val plainDonut = Tuple3("Plain Donut", "Tasty", 2)
Now, let's store all our donuts tuples into a list as follows:
val donutList = List(glazedDonut, strawberryDonut, plainDonut)
Let's also assume that the donutList is returned to us by a call to some API which looked up the donut details from a database.
What if you would like to find the price of a Plain Donut in that list? To do this, we will loop through our donutList variable using the foreach() function.
val priceOfPlainDonut = donutList.foreach { tuple => {
tuple match {
case ("Plain Donut", taste, price) => println(s"Donut type = Plain Donut, price = $price")
case d if d._1 == "Glazed Donut" => println(s"Donut type = ${d._1}, price = ${d._3}")
case _ => None
}
}
}
You should see the following output when you run your Scala application in IntelliJ:
Step 4: How to use pattern matching on Tuples
Donut type = Glazed Donut, price = 2.5
Donut type = Plain Donut, price = 2
NOTE:
- We've used two flavors of case expressions similar to what we've learned from the previous Pattern Matching tutorial.
- The first case expression
case ("Plain Donut", taste, price)
will match for Plain Donut and then store the taste and price data points into variables which you can then referenced. - The second case expression
case d if d._1 == "Glazed Donut"
extracts a local variable named d and will only match on Glazed Donut. - We've also provided a default case using the wildcard underscore _ and simply return None.
5. Shortcut for creating Tuples
Using Tuples is so common that Scala has an elegant shortcut which we can use to create Tuples. You can simply enclose your data points within ()
println("\nStep 5: Shortcut for creating Tuples")
val chocolateDonut = ("Chocolate Donut", "Very Tasty", 3.0)
println(s"Chocolate donut taste level = ${chocolateDonut._2}, price = ${chocolateDonut._3}")
You should see the following output when you run your Scala application in IntelliJ:
Step 5: Shortcut for creating Tuples
Chocolate donut taste level = Very Tasty, price = 3.0
Summary
In this tutorial, we went over the following:
- How to create a Tuple with two data points using the Tuple2 class
- How to access each individual elements in a Tuple
- How to create and use Tuples with more than two data points
- How to use pattern matching on a list of tuples
- How to easily create Tuples using () brackets
Tip
- You can write the pattern matching in Step 4 in a more elegant way as follows:
println("\nTip 1: A more elegant pattern matching within foreach function")
donutList.foreach {
case ("Plain Donut", taste, price) => println(s"Donut type = Plain Donut, price = $price")
case d if d._1 == "Glazed Donut" => println(s"Donut type = ${d._1}, price = ${d._3}")
case _ => None
}
Source Code
The source code is available on the allaboutscala GitHub repository.
What's Next
In the next tutorial, I will go over the use of Option, Some and None as a replacement for having to make use of null in your codebase.
Stay tuned!