Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there way to create tuple from list(without codegeneration)?

Sometimes there are needs to create tuples from small collections(for example scalding framework).

def toTuple(list:List[Any]):scala.Product = ...
like image 782
yura Avatar asked Jul 03 '12 06:07

yura


Video Answer


3 Answers

You really don't want your method to return Product since this is uselessly vague. If you want to be able to use the returned object as a tuple, then you'll have to know its arity. So what you can do is have a series of toTupleN methods for different arities. For convenience, you can add these as implicit methods on Seq.

How about this:

class EnrichedWithToTuple[A](elements: Seq[A]) {
  def toTuple2 = elements match { case Seq(a, b) => (a, b) }
  def toTuple3 = elements match { case Seq(a, b, c) => (a, b, c) }
  def toTuple4 = elements match { case Seq(a, b, c, d) => (a, b, c, d) }
  def toTuple5 = elements match { case Seq(a, b, c, d, e) => (a, b, c, d, e) }
}
implicit def enrichWithToTuple[A](elements: Seq[A]) = new EnrichedWithToTuple(elements)

and use it like:

scala> List(1,2,3).toTuple3
res0: (Int, Int, Int) = (1,2,3)
like image 193
dhg Avatar answered Oct 02 '22 13:10

dhg


If, as @dhg observed, you know the expected arity up front you can do something useful here. Using shapeless you could write,

scala> import shapeless._
import shapeless._

scala> import Traversables._
import Traversables._

scala> import Tuples._
import Tuples._

scala> List(1, 2, 3).toHList[Int :: Int :: Int :: HNil] map tupled
res0: Option[(Int, Int, Int)] = Some((1,2,3))
like image 34
Miles Sabin Avatar answered Oct 02 '22 11:10

Miles Sabin


If you don't know the arity up front and want to do a terrible terrible hack, you can do this:

def toTuple[A <: Object](as:List[A]):Product = {
  val tupleClass = Class.forName("scala.Tuple" + as.size)
  tupleClass.getConstructors.apply(0).newInstance(as:_*).asInstanceOf[Product]
}
toTuple: [A <: java.lang.Object](as: List[A])Product

scala> toTuple(List("hello", "world"))
res15: Product = (hello,world)
like image 22
Kim Stebel Avatar answered Oct 02 '22 12:10

Kim Stebel