Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to slice a tuple in scala

Tags:

I am trying to slice a tuple, removing the last two items. I tried using the list drop/take methods but I can't succeed to get a tuple back.

Here is the approach I tried :

scala> val myTuple = (1, 2, 4, 5, 0, 5) myTuple: (Int, Int, Int, Int, Int, Int) = (1,2,4,5,0,5)  scala> val myList = myTuple.productIterator.toList myList: List[Any] = List(1, 2, 4, 5, 0, 5)  scala> val mySubList = myList.dropRight(2) mySubList: List[Any] = List(1, 2, 4, 5)  scala> val mySubTuple = ??? 

I saw here that list to tuple isn't (yet?) possible in scala.

Are there other ways to get that subtuple (without dealing with myTuple._1, myTuple._2...) ?

like image 285
kheraud Avatar asked Jun 19 '12 09:06

kheraud


People also ask

What is a tuple in Scala?

In Scala, a tuple is a value that contains a fixed number of elements, each with its own type. Tuples are immutable. Tuples are especially handy for returning multiple values from a method.

What is the difference between list and tuple in Scala?

Lists are mutable(values can be changed) whereas tuples are immutable(values cannot be changed).

What is a tuple2?

A 1‑tuple is called a single (or singleton), a 2‑tuple is called an ordered pair or couple, and a 3‑tuple is called a triple (or triplet). The number n can be any nonnegative integer.


1 Answers

This is the sort of thing that shapeless can do in a generic way, involving conversion into an HList.

First - get shapeless. Then run scala with dependent method types switched on (on by default in 2.10):

C:\Scala\sdk\scala-2.9.2\bin>scala -Ydependent-method-types Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_04). Type in expressions to have them evaluated. Type :help for more information. 

Add shapeless to the classpath:

scala> :cp C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar Added 'C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar'.  Your new classpath is: "C:\tibco\tibrv\8.2\lib\tibrvnative.jar;C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar" 

Now let us play!

scala> (1, 2.3, 'a, 'b', "c", true) res0: (Int, Double, Symbol, Char, java.lang.String, Boolean) = (1,2.3,'a,b,c,true) 

We must import shapeless

scala> import shapeless._; import Tuples._; import Nat._ import shapeless._ import Tuples._ import Nat._ 

We turn our tuple into an HList

scala> res0.hlisted res2: shapeless.::[Int,shapeless.::[Double,shapeless.::[Symbol,shapeless.::[Char,shapeless.::[java.lang.String,shapeless.::[Boolean,shapeless.HNil]]]]]] = 1 :: 2.3 :: 'a :: b :: c :: true :: HNil 

Then we take the first 4 (notice that _4 is a type parameter, not a method argument)

scala> res2.take[_4] res4: shapeless.::[Int,shapeless.::[Double,shapeless.::[Symbol,shapeless.::[Char, shapeless.HNil]]]] = 1 :: 2.3 :: 'a :: b :: HNil 

Now convert back to a tuple

scala> res4.tupled res5: (Int, Double, Symbol, Char) = (1,2.3,'a,b) 

We could shorten this:

val (a, b, c, d) = sixtuple.hlisted.take[_4].tupled  //a, b, c and d would all have the correct inferred type 

This of course generalizes to the first M elements of an N-tuple

like image 112
oxbow_lakes Avatar answered Oct 11 '22 10:10

oxbow_lakes