332

7
+7  Q:

## Simple question about tuple of scala

I'm new to scala, and what I'm learning is `tuple`.

I can define a tuple as following, and get the items:

``````val tuple = ("Mike", 40, "New York")
println("Name: " + tuple._1)
println("Age: " + tuple._2)
println("City: " + tuple._3)
``````

My question is:

1. How to get the length of a tuple?
2. Is tuple mutable? Can I modify its items?
3. Is there any other useful operation we can do on a tuple?

+4  A:
1. You know the size of a tuple, it's part of it's type. For example if you define a function `def f(tup: (Int, Int))`, you know the length of `tup` is 2 because values of type `(Int, Int)` (aka `Tuple2[Int, Int]`) always have a length of 2.
2. No.
3. Not really. Tuples are useful for storing a fixed amount of items of possibly different types and passing them around, putting them into data structures etc. There's really not much you can do with them, other than creating tuples, and getting stuff out of tuples.
+15  A:

1] `tuple.productArity`

2] No.

3] Some interesting operations you can perform on tuples: (a short REPL session)

``````scala> val x = (3, "hello")
x: (Int, java.lang.String) = (3,hello)

scala> x.swap
res0: (java.lang.String, Int) = (hello,3)

scala> x.toString
res1: java.lang.String = (3,hello)

scala> val y = (3, "hello")
y: (Int, java.lang.String) = (3,hello)

scala> x == y
res2: Boolean = true

scala> x.productPrefix
res3: java.lang.String = Tuple2

scala> val xi = x.productIterator
xi: Iterator[Any] = non-empty iterator

scala> while(xi.hasNext) println(xi.next)
3
hello
``````

See scaladocs of Tuple2, Tuple3 etc for more.

@Rahuλ G, thank you again!
@Freewind, Welcome!
+4  A:

`Tuples` are immutable, but, like all cases classes, they have a copy method that can be used to create a new `Tuple` with a few changed elements:

``````scala> (1, false, "two")
res0: (Int, Boolean, java.lang.String) = (1,false,two)

scala> res0.copy(_2 = true)
res1: (Int, Boolean, java.lang.String) = (1,true,two)

scala> res1.copy(_1 = 1f)
res2: (Float, Boolean, java.lang.String) = (1.0,true,two)
``````
+9  A:

One thing that you can also do with a tuple is to extract the content using the `match` expression:

``````def tupleview( tup: Any ){
tup match {
case (a: String, b: String) =>
println("A pair  of strings: "+a + " "+ b)
case (a: Int, b: Int, c: Int) =>
println("A triplet of ints: "+a + " "+ b + " " +c)
case _ => println("Unknown")
}
}

tupleview( ("Hello", "Freewind"))
tupleview( (1,2,3))
``````

Gives:

``````A pair  of strings: Hello Freewind
A triplet of ints: 1 2 3
``````
@olle, thanks for this nice example
+2  A:

``````val tuple = ("Mike", 40, "New York")
tuple match  {
case (name, age, city) =>{
println("Name: " + name)
println("Age: " + age)
println("City: " + city)
}
}
``````

Edit: in fact it's rather a feature of pattern matching and case classes, a tuple is just a simple example of a case class...

+2  A:

A very useful thing that you can use tuples for is to return more than one value from a method or function. Simple example:

``````// Get the min and max of two integers
def minmax(a: Int, b: Int): (Int, Int) = if (a < b) (a, b) else (b, a)

// Call it and assign the result to two variables like this:
val (x, y) = minmax(10, 3)     // x = 3, y = 10
``````
+2  A:

Concerning question 3:

A useful thing you can do with Tuples is to store parameter lists for functions:

``````def f(i:Int, s:String, c:Char) = s * i + c
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println((f _).tupled(t)))
//--> chachacha!
//--> borabora.
``````

 As Randall remarks, you'd better use something like this in "real life":

``````def f(i:Int, s:String, c:Char) = s * i + c
val g = (f _).tupled
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println(g(t)))
``````

In order to extract the values from tuples in the middle of a "collection transformation chain" you can write:

``````val words = List((3, "cha"),(2, "bora")).map{ case(i,s) => s * i }
``````

Note the curly braces around the case, parentheses won't work.

Note that in this construction, you're going to synthesize the tupled versions of the function that was itself lifted from method `f` *on each iteration of the `foreach`*.