This is an excerpt from the 1st edition of the Scala Cookbook (partially modified for the internet). This is Recipe 10.27, “Scala Tuples, for When You Just Need a Bag of Things”
Problem
When writing a Scala application, you want to create a small collection of heterogeneous elements.
Solution
A tuple gives you a way to store a group of heterogeneous items in a container, which is useful in many situations.
Create a tuple by enclosing the desired elements between parentheses. This is a two- element tuple:
scala> val d = ("Amanda", 95) d: (String, Int) = (Amanda,95)
Notice that it contains two different types. The following example shows a three-element tuple:
scala> case class Person(name: String) defined class Person scala> val t = (3, "Three", new Person("Al")) t: (Int, java.lang.String, Person) = (3,Three,Person(Al))
You can access tuple elements using an underscore construct:
scala> t._1 res1: Int = 3 scala> t._2 res2: java.lang.String = Three scala> t._3 res3: Person = Person(Al)
I often prefer to assign them to variables using pattern matching:
scala> val(x, y, z) = (3, "Three", new Person("Al")) x: Int = 3 y: String = Three z: Person = Person(Al)
A nice feature of this approach is that if you don’t want all of the elements from the tuple, just use the _
wildcard character in place of the elements you don’t want:
scala> val (x, y, _) = t x: Int = 3 y: java.lang.String = Three scala> val (x, _, _) = t x: Int = 3 scala> val (x, _, z) = t x: Int = 3 z: Person = Person(Al)
A two-element tuple is an instance of the Tuple2
class, and a tuple with three elements is an instance of the Tuple3
class. (More on this in the Discussion.) As shown earlier, you can create a Tuple2
like this:
scala> val a = ("AL", "Alabama") a: (java.lang.String, java.lang.String) = (AL,Alabama)
You can also create it using these approaches:
scala> val b = "AL" -> "Alabama" b: (java.lang.String, java.lang.String) = (AL,Alabama) scala> val c = ("AL" -> "Alabama") c: (java.lang.String, java.lang.String) = (AL,Alabama)
When you check the class created by these examples, you’ll find they’re all of type Tuple2
:
scala> c.getClass res0: java.lang.Class[_ <: (java.lang.String, java.lang.String)] = class scala.Tuple2
This syntax is very convenient for other uses, including the creation of maps:
val map = Map("AL" -> "Alabama")
Discussion
The tuple is an interesting construct. There is no single “Tuple” class; instead, the API defines tuple case classes from Tuple2
through Tuple22
, meaning that you can have from 2 to 22 elements in a tuple.
A common use case for a tuple is returning multiple items from a method. See Recipe 5.5, “Defining a Method That Returns Multiple Items (Tuples)”, for an example of this.
Though a tuple isn’t a collection, you can treat a tuple as a collection when needed by creating an iterator:
scala> val x = ("AL" -> "Alabama") x: (java.lang.String, java.lang.String) = (AL,Alabama) scala> val it = x.productIterator it: Iterator[Any] = non-empty iterator scala> for (e <- it) println(e) AL Alabama
Be aware that like any other iterator, after it’s used once, it will be exhausted. Attempting to print the elements a second time yields no output:
scala> for (e <- it) println(e) // no output here
Create a new iterator if you need to loop over the elements a second time.
You can also convert a tuple to a collection:
scala> val t = ("AL", "Alabama") t: (String, String) = (AL,Alabama) scala> t.productIterator.toArray res0: Array[Any] = Array(AL, Alabama)
See Also
- The Scala Tuple2 class
- Recipe 5.5, “Defining a Method That Returns Multiple Items (Tuples)”
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |