1. Overview

Sometimes we need a way to group several elements together that may or may not be related. For this very scenario, we can use a tuple, which simply put is an ordered collection of objects of different types.

In a previous tutorial, we took a look at a neat third-party library called javatuples which offers support for tuples in Java. Thankfully, Scala already has a built-in tuple type, which is an immutable data structure that we can use for holding up to 22 elements with different types.

In this quick tutorial, we’ll learn how to create a tuple in Scala, access its elements, and review some of the most important methods and discuss when to use them.

2. Creating Tuples

Creating a tuple is very easy and doesn’t require any boilerplate code. It’s just a matter of enclosing its elements in parentheses:

val tuple: (String, Int) = ("Joe", 34)

Here we’ve created a tuple containing a String element and an Int element. It’s also possible to create them using arrow syntax:

val stillTuple: (String, Int) = "Joe" -> 34

In Scala, tuples are defined using a series of classes named Tuple2, Tuple3 all the way through to Tuple22. In practice, we’ll probably never need to use these classes directly, but it is interesting to know what is happening internally.

Let’s take a quick look at how we can create a tuple with a few more elements:

val tuple3: (String, Int, Boolean) = ("Joe", 34, true)
val tuple4: (String, Int, Boolean, Char) = ("Joe", 34, true, 'A')

Bear in mind that (String, Int, Boolean) is just syntactic sugar for Tuple3[String, Int, Boolean].

In the next section, we’ll take a look at how we can access elements in a tuple.

3. Accessing Elements

We can access the elements inside a tuple in one of two ways. The first approach is to access elements by position using the underscore syntax.

For example can use the _1 method to access the first element, _2 to access second and so on (up to 22):

val name = tuple._1 
val age = tuple._2

We can also assign a tuple to multiple variables variable using pattern matching:

val (userName, userAge) = tuple

Here, we take the tuple apart and assign the first element to a variable called userName whose inferred type is String. Likewise, we assign the second element to a variable called userAge with an inferred type of Int.

It’s also possible to omit some elements when we declare the variables using an underscore in the desired place:

val (_, myAge) = tuple

4. Typical Use Cases

Tuples can be particularly useful when we need to return multiple values from a function or pass multiple values to a function. This may be preferable instead of using a case class, particularly if we need to return unrelated values.

4.1. Returning Multiple Values

A particularly good example of returning a tuple is a partition method:

def partition[A](xs: List[A])(predicate: A => Boolean): (List[A], List[A]) = {
  xs.foldRight((List.empty[A], List.empty[A])) {
    case (a, (lefts, rights)) =>
      if (predicate(a)) (a :: lefts, rights) else (lefts, a :: rights)
  }
}
val (evens, odds) = partition(List(1, 3, 4, 5, 2))(_ % 2 == 0)

In this example, the partition method returns a pair of List. The first list consists of all the elements which satisfy a given predicate and the second consists of all the elements that don’t.

4.2. Passing Multiple Values

Likewise, we can also use a tuple for passing multiple parameters to a one-parameter function. We even have a special tupled method that converts a function with more than one parameter, to a function which accepts a tuple as the only argument:

val data = Map(
    "Joe" -> 34,
    "Mike" -> 16,
    "Kelly" -> 21
  )

case class User(name: String, isAdult: Boolean)

val createUser: (String, Int) => User = (name, age) => User(name, age >= 18)
val users = data.map(createUser.tupled)

In the above example, we transform our data map to User class using createUser function. If we forget to call .tupled method it would fail with the following error:

type mismatch; 
found : (String, Int) => User 
required: ((String, Int)) => ? 
val users = data.map(createUser)

The compiler is telling us that we try to pass two arguments function into a place where one argument function with tuple parameter is needed.

5. Conclusion

In this quick tutorial, we introduced the tuple type in Scala. We learned how to create tuples and how to access values inside of tuple objects. We also reviewed several useful methods and walked through some typical use cases.

As always, the full source code of the article is available over on GitHub.

guest
0 Comments
Inline Feedbacks
View all comments