Is there a Scala equivalent of the Python list unpack (a.k.a. "*") operator?


Question

In Python, we have the star (or "*" or "unpack") operator, that allows us to unpack a list for convenient use in passing positional arguments. For example:

range(3, 6)
args = [3, 6]
# invokes range(3, 6)
range(*args)

In this particular example, it doesn't save much typing, since range only takes two arguments. But you can imagine that if there were more arguments to range, or if args was read from an input source, returned from another function, etc. then this could come in handy.

In Scala, I haven't been able to find an equivalent. Consider the following commands run in a Scala interactive session:

case class ThreeValues(one: String, two: String, three: String)

//works fine
val x = ThreeValues("1","2","3")

val argList = List("one","two","three")

//also works
val y = ThreeValues(argList(0), argList(1), argList(2))

//doesn't work, obviously
val z = ThreeValues(*argList)

Is there a more concise way to do this besides the method used in val y?

1
22
2/22/2013 10:54:08 PM

Accepted Answer

There is something similar for functiones: tupled It converts a function that takes n parameters into a function that takes one argument of type n-tuple.

See this question for more information: scala tuple unpacking

Such a method for arrays wouldn't make much sense, because it would only work with functions with multiple arguments of same type.

4
5/23/2017 11:47:32 AM

There is no direct equivalent in scala. The closest thing you will find is the usage of _*, which works on vararg methods only. By example, here is an example of a vararg method:

def hello( names: String*) {
  println( "Hello " + names.mkString(" and " ) )
}

which can be used with any number of arguments:

scala> hello()
Hello
scala> hello("elwood")
Hello elwood
scala> hello("elwood", "jake")
Hello elwood and jake

Now, if you have a list of strings and want to pass them to this method, the way to unpack it is through _*:

scala> val names = List("john", "paul", "george", "ringo")
names: List[String] = List(john, paul, george, ringo)
scala> hello( names: _* )
Hello john and paul and george and ringo    

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon