Learn How To Use Tuples (Pattern Match)

By Nadim Bahadoor | Last updated: July 25, 2017 at 13:38 pm

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 leve 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

This concludes our tutorial on Learn How To Use Tuples (Pattern Match) and I hope you've found it useful!

 

Stay in touch via Facebook and Twitter for upcoming tutorials!

 

Don't forget to like and share this page :)

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!

Nadim Bahadoor on FacebookNadim Bahadoor on GithubNadim Bahadoor on LinkedinNadim Bahadoor on Twitter
Nadim Bahadoor
Senior Software Developer | Nephila Capital
Founder of allaboutscala.com. I have over 10 years of experience in building large scale real-time trading systems in the financial industry. Passionate about Distributed Systems, Scala, Big Data and Functional Programming. Stay in touch for upcoming tutorials!
Other allaboutscala.com tutorials you may like:

Share this article on

  • Divus Iuilius

    Do you know of a way to use pattern matching to (Produce / Select) two data types? Int & String If the case “al” | “alabama” => var = .0875 & Alabama I use the Int Data for retail State Taxes and the Name of the State for println. The State Variable tax Integer is used to calculate the retail tax of each purchase show the name of the selected State on ea recite next to the calculated retail Sales Tax of the purchase. Can you use Tuples in Pattern Matching to do this? Case “al” | “alabama” => variable = Int and String and default to String = “Alabama” Int = .0901 or % 9.01 Sales Taxes

    • allaboutscala

      Hi Divus,
      The function below will produce a Tuple representing a state along with its tax rate. The syntax is a bit explicit for the purpose of your use case.
      Hope this helps.
      Cheers,
      Nadim


      def taxRateByState(state: String): (Double, String) = {
      state match {
      case "AL" | "Alabama" => (0.1234, state)
      case "NJ" | "New Jersey" => (0.2345, state)
      case s @ _ => (0.1111, s)
      }
      }
      println(s"${taxRateByState("AL")}")
      println(s"${taxRateByState("New Jersey")}")
      println(s"${taxRateByState("unknown state")}")

      • Divus Iuilius

        (ಠ_ಠ) Geeez! I feel like a complete idiot! It not only looks obvious, it makes perfect sense! And yet, I overlooked my own DAMN chosen ‘state” func variable. Sometimes the answer is just SITTING there STARRING me RIGHT in the FACE!
        After reading about Tuples, I could see that there might be an answer. I just couldn’t put it all to together.

        And What is this? ===> “s @ _ => (0.1111, s)” What is the default value of this?

        • allaboutscala

          Hi Divus, you can simplify the method as follows. There is also no need to maintain a var stateTax.

          object Purchase {
          def getStateTaxNum(state: String): (String, Double) = {
          state.toLowerCase() match {
          case "al" | "alabama" => (state, .085)
          case "ak" | "alaska" => (state, .076)
          case "az" | "arizona" => (state, .0825)
          case "ar" | "arkansas" => (state, .093)
          case "ca" | "california" => (state, .0825)
          case "co" | "colorado" => (state, .075)
          case "ct" | "connecticut" => (state, .0635)
          case "dc" | "district colombia" => (state, .0575)
          case _ => (state, 0)
          }
          }
          }

          val (state, tax) = Purchase.getStateTaxNum("california")
          println(s"state = $state, tax = $tax")

          “s @ _” means capturing a variable called s for state. Along with the wildcard _, this is your default case if you need to capture one.

      • Divus Iuilius

        Once again Thank You for your assistance! Here’s what I came up with:
        I simply call the state: String and the stateTax variables later.

        object purchase {

        def getStateTaxNum(state: String): Double = {
        var stateTax: Double = 0
        if (state == null) {
        stateTax
        }
        state.toLowerCase() match {

        case “al” | “alabama” => stateTax = .085
        case “ak” | “alaska” => stateTax = .076
        case “az” | “arizona” => stateTax = .0825
        case “ar” | “arkansas” => stateTax = .093
        case “ca” | “california” => stateTax = .0825
        case “co” | “colorado” => stateTax = .075
        case “ct” | “connecticut” => stateTax = .0635
        case “dc” | “district colombia” => stateTax = .0575
        case _ => stateTax = 0
        }
        stateTax
        }

        val returnedStateTax: Double = purchase.getStateTaxNum(state)

        // This is how I passed the state variable through the getStatTaxNum (Func), purchase (Object) to the Main Function.

        also

        I set the String to “getState = state.map(state => state.toUpper)” late for display purposes.

        excerpt[…]

  • Divus Iuilius

    I ran into wall on the SBT Jar Issue. I followed the simple instructions for the SBT compiler. > / Run and received a compile ERROR something about Scala.io.StdIn compatibility issue not recognized. I checked the Scala Version and used “++ 2.12.1” to Update the local scala version. it defiantly made a difference. But! the Scala.io.StdIn readInt() function is totally glichy. The function totally fails. Cant take input what so ever. Also, Are there any issues using Java Lib and Scala Lib at the same time in a the same scala File while compiling in SBT? The file works fine until I put through the SBT Run compiler. Very strange!