For example, there is a Scala array val A = Array("please", "help", "me"). How to choose a random element from this array?
6 Answers
import scala.util.Random
val A = Array("please", "help", "me")
Random.shuffle(A.toList).head
5 Comments
headOption, since the Seq (Array here) might be empty.import scala.util.Random
val A = List(1, 2, 3, 4, 5, 6)
A(Random.nextInt(A.size))
3 Comments
A.size equals to zero. Never forget about edge casesA.lift(Random.nextInt(A.size)) which will give you Option[Int]A.size is 0import java.util.Random
// ...
val rand = new Random(System.currentTimeMillis())
val random_index = rand.nextInt(A.length)
val result = A(random_index)
4 Comments
A.length equals to zero. Never forget about edge casesWe can also add some safety with the Option monad (using the lift method)
Actually, when using this method on any collection, even if your collection is empty, or your random index is out of boundaries, your result will always be an Option.
Drive safe <3
def getRandElemO[T](arr: Array[T]): Option[T] =
if (arr.isEmpty) None
else arr.lift(util.Random.nextInt(arr.length))
// or the one liner:
// def getRandElemO[T](arr: Array[T]): Option[T] =
// arr.headOption.flatMap(_ => arr.lift(util.Random.nextInt(arr.length)))
1 Comment
If you want a more idiomatic solution, consider using the typeclass pattern (implicit classes in scala).
implicit class ListOps[A](list: List[A]) {
def getRandomElement: Option[A] = list match {
case Nil => None
case _ => list.lift(scala.util.Random.nextInt(list.size))
}
def randomChoice(n: Int): Option[List[A]] =
(1 to n).toList.foldLeft(Option(List[A]()))((acc, e) => getRandomElement.flatMap(r => acc.map(a => a :+ r)))
}
Now if the implicit class is in scope, you can:
val randomElement: Option[String] = List("this", "is", "a", "list").getRandomElement
If you are sure that the option contains some value, you can use the get method.
randomElement.get // This will return a String (or a NotSuchElementExeption)
Nonetheless, pattern matching or getOrElse are recommended:
randomElement match {
case None => ??? // This is what you do when a None is encounter (e.g. for empty lists)
case Some(result) => ??? // The variable result contains a string.
Note that the randomChoice method assumes substitution of elements.
Comments
A better answer that does not involve reshuffling the array at all would be this:
import scala.util.Random
object sample {
//gets random element from array
def arr[T](items:Array[T]):T = {
items(Random.nextInt(items.length))
}
}
This also works generically