1
def swapElementsOfArray(array: Array[Int]) = 
    array match {
        case Array(x, y, z @ _*) => Array(y, x) ++ z
        case _ => array
}

I don't get how @ _* is used here. can anyone help to explain that? thank you in advance.

yu.sun
  • 69
  • 12

2 Answers2

2

The operator _* makes reference to a sequence of elements, in your case, it'd be the "tail" of the array.

The operator @ allows you to bind a matched pattern to a variable, in your case "z"

So with z @ _* you are assigning to Z the rest of the array you are not using but you need to refer to it later.

val a= Array(2, 1, 3, 5, 3, 2)
def swapElementsOfArray(array: Array[Int]) =
  array match {
    case Array(x, y, z @ _*) => Array(y, x) ++ z
    case _ => array
  }

swapElementsOfArray(a).toString

res0: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 5, 3, 2

z would be "3,5,3,2" you don't need it for use but you need the reference.

vikscool
  • 1,293
  • 1
  • 10
  • 24
Siodh
  • 126
  • 1
  • 8
1

In this specific example _* means "the rest of the array".

The z @ part is standard pattern match syntax for binding a variable name to a pattern

Please note that the _* operator is a general operator that applies to any vararg parameter, and it's sometimes referred to as the "splat operator".

You can read about it in the specification: https://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#repeated-parameters

Here's the relevant sentence:

The only exception to this rule is if the last argument is marked to be a sequence argument via a _* type annotation. If m above is applied to arguments (e1,…,en,e′: _*), then the type of m in that application is taken to be (p1:T1,…,pn:Tn,ps:scala.Seq[S])

This applies to both matching and passing varargs. For example, the splat operator can be used to pass a sequence where a vararg is expected.

Example:

val s = Seq(1, 2, 3)
val a1 = Array(s) // does not compile
val a2 = Array(s: _*) // compiles, s is passed as vararg

a2 match {
  case Array(s @ _*) => s // s now contains all the elements of a2
}

a2 match {
  case Array(head, tail @ _*) => head // tail contains all the elements except the first
  case _ => ??? // empty list!
}
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235