Scala FAQ: Can you share some examples of using tuples in Scala?
Getting started with tuples
A Scala tuple is a class that can contain a miscellaneous collection of elements. I like to think of them as a little bag or container you can use to hold things and pass them around.
You create a tuple with the following syntax, enclosing its elements in parentheses. Here's a tuple that contains an Int
and a String
:
val stuff = (42, "fish")
This creates a specific instance of a tuple called a Tuple2
, which we can demonstrate in the REPL:
scala> val stuff = (42, "fish") stuff: (Int, java.lang.String) = (42,fish) scala> stuff.getClass res0: java.lang.Class[_ <: (Int, java.lang.String)] = class scala.Tuple2
A tuple isn't actually a collection; it's a series of classes named Tuple2
, Tuple3
, etc., through Tuple22
. You don't have to worry about that detail, other than knowing that you can have anywhere from two to twenty-two items in a tuple. (And in my opinion, if you have twenty-two miscellaneous items in a bag, you should probably re-think your design.)
Accessing tuple elements
You can access tuple elements using an underscore syntax. The first element is accessed with _1
, the second element with _2
, and so on, like this:
scala> val things = ("a", 1, 3.5) things: (java.lang.String, Int, Double) = (a,1,3.5) scala> println(things._1) a scala> println(things._2) 1 scala> println(things._3) 3.5
Use variable names to access tuple elements
When referring to a Scala tuple you can also assign names to the elements in the tuple. I like to do this when returning miscellaneous elements from a method. To demonstrate the syntax, let's create a very simple method that returns a tuple:
def getUserInfo = ("Al", 42, 200.0)
Now we can call that method, and assign the tuple results directly to variables, like this:
val(name, age, weight) = getUserInfo
Here's what this looks like in the REPL:
scala> def getUserInfo = ("Al", 42, 200.0) getUserInfo: (java.lang.String, Int, Double) scala> val(name, age, weight) = getUserInfo name: java.lang.String = Al age: Int = 42 weight: Double = 200.0
It's shown in the REPL results, but we'll further confirm that we can indeed access the values by variable name:
scala> name res4: java.lang.String = Al scala> age res5: Int = 42 scala> weight res6: Double = 200.0
That's pretty nice.
In a cool, related feature, if you only want to access some of the elements, you can ignore the others by using an underscore placeholder for the elements you want to ignore. Imagine you want to ignore theweight
in our example:
scala> val(name, age, _) = getUserInfo name: java.lang.String = Al age: Int = 42
Or suppose you want to ignore the age
and weight
:
scala> val(name, _, _) = getUserInfo name: java.lang.String = Al
Again, that's good stuff.
Iterating over a Scala tuple
As mentioned, a tuple is not a collection; it doesn't descend from any of the collection traits or classes. However, you can treat it a little bit like a collection by using its productIterator
method.
Here's how you can iterate over the elements in a tuple:
scala> val t = ("Al", 42, 200.0) t: (java.lang.String, Int, Double) = (Al,42,200.0) scala> t.productIterator.foreach(println) Al 42 200.0
The tuple toString method
The tuple toString
method gives you a nice representation of a tuple:
scala> t.toString res9: java.lang.String = (Al,42,200.0) scala> println(t.toString) (Al,42,200.0)
Creating a tuple with ->
In another cool feature, you can create a tuple using this syntax:
1 -> "a"
This creates a Tuple2
, which we can demonstrate in the REPL:
scala> 1 -> "a" res1: (Int, java.lang.String) = (1,a) scala> res11.getClass res2: java.lang.Class[_ <: (Int, java.lang.String)] = class scala.Tuple2
You'll see this syntax a lot when creating maps:
scala> val map = Map(1->"a", 2->"b") map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b)