Deden Bangkit Deden Bangkit - 1 month ago 5
Scala Question

Shuffle some sequence of List in Scala

I'm using

scala.util.Random
, then I know how to shuffle a list. It's very useful to randomize an order inside Array list, for example:

val List(a, b, c, d) = Random.shuffle(List(1,2,3,4))
it will result

a = 1
b = 3
c = 2
d = 4


the result of a, b, c, d could be any random value between 1 to 4.
But the thing is we can't do this:

val a:List = List(1,2,Random.shuffle(3,4,5))


please share if you guys have any clue for this case. If no, please explain why.

Thanks!

Answer

val a:List = List(1,2,Random.shuffle(3,4,5)) this line would give type error

Reason

Shuffle does not take var args and also List apply method does not take both elements and List as arguments simultaneously. This is how shuffle is declared in Standard Library.

 def shuffle[T, CC[X] <: TraversableOnce[X]](xs: CC[T])(implicit bf: CanBuildFrom[CC[T], T, CC[T]]): CC[T] = {
    val buf = new ArrayBuffer[T] ++= xs

    def swap(i1: Int, i2: Int) {
      val tmp = buf(i1)
      buf(i1) = buf(i2)
      buf(i2) = tmp
    }

    for (n <- buf.length to 2 by -1) {
      val k = nextInt(n)
      swap(n - 1, k)
    }

    (bf(xs) ++= buf).result()
  }

Instead do this

val a = List(1, 2) ++ Random.shuffle(List(3, 4, 5))

If you want more friendly API just declare an implicit like this

implicit class ListUtils[A](list: List[A]) {
  import scala.util.Random
  def addShuffling(xs: A*) = list ++ Random.shuffle(xs.toList)
}

Scala REPL

scala> import scala.util._

scala>  implicit class ListUtils[A](list: List[A]) {
     |       def addShuffling(xs: A*) = list ++ Random.shuffle(xs.toList)
     |     }
defined class ListUtils

scala> List(1, 2).addShuffling(3, 4, 5)
res3: List[Int] = List(1, 2, 5, 3, 4)

Vector would be better for long lists. Use vector implementation for long lists

implicit class VectorUtils[A](vec: Vector[A]) {
   def addShuffling(xs: A*) = vec ++ Random.shuffle(xs.toVector)
}

Scala REPL

implicit class VectorUtils[A](vec: Vector[A]) {
      import scala.util.Random
      def addShuffling(xs: A*) = vec ++ Random.shuffle(xs.toVector)
    }

    Vector(1, 2).addShuffling(3, 4, 5)

// Exiting paste mode, now interpreting.

defined class VectorUtils
res1: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)
Comments