Oswaldo
Oswaldo

Reputation: 523

How to explain that "Set(someList : _*)" results the same as "Set(someList).flatten"

I found a piece of code I wrote some time ago using _* to create a flattened set from a list of objects.

The real line of code is a bit more complex and as I didn't remember exactly why was that there, took a bit of experimentation to understand the effect, which is actually very simple as seen in the following REPL session:

scala> val someList = List("a","a","b")
someList: List[java.lang.String] = List(a, a, b)

scala> val x = Set(someList: _*)
x: scala.collection.immutable.Set[java.lang.String] = Set(a, b)

scala> val y = Set(someList).flatten
y: scala.collection.immutable.Set[java.lang.String] = Set(a, b)

scala> x == y
res0: Boolean = true

Just as a reference of what happens without flatten:

scala> val z = Set(someList)
z: scala.collection.immutable.Set[List[java.lang.String]] = Set(List(a, a, b))

As I can't remember where did I get that idiom from I'd like to hear about what is actually happening there and if there is any consequence in going for one way or the other (besides the readability impact)

P.S.: Maybe as an effect of the overuse of underscore in Scala language (IMHO), it is kind of difficult to find documentation about some of its use cases, specially if it comes together with a symbol commonly used as a wildcard in most search engines.

Upvotes: 1

Views: 103

Answers (1)

om-nom-nom
om-nom-nom

Reputation: 62835

_* is for expand this collection as if it was written here literally, so

val x = Set(Seq(1,2,3,4): _*)

is the same as

val x = Set(1,2,3,4)

Whereas, Set(someList) treats someList as a single argument.

To lookup funky symbols, you could use symbolhound

Upvotes: 4

Related Questions