it-swarm.com.de

Wie wählt man ein zufälliges Element aus einem Array in Scala aus?

Zum Beispiel gibt es ein Scala-Array val A = Array("please", "help", "me"). Wie wählt man ein zufälliges Element aus diesem Array?

45
sam
import Java.util.Random
// ...
val Rand = new Random(System.currentTimeMillis())
val random_index = Rand.nextInt(A.length)
val result = A(random_index)
32
topless
import scala.util.Random

val A = Array("please", "help", "me")
Random.shuffle(A.toList).head
89
user1338062
import scala.util.Random

val A = List(1, 2, 3, 4, 5, 6)
A(Random.nextInt(A.size))
36
ahogue

Wenn Sie eine idiomatischere Lösung suchen, sollten Sie das Typenklassenmuster (implizite Klassen in Scala) in Betracht ziehen. 

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)))
}

Wenn die implizite Klasse jetzt im Gültigkeitsbereich liegt, können Sie:

val randomElement: Option[String] = List("this", "is", "a", "list").getRandomElement

Wenn Sie sicher sind, dass die Option einen Wert enthält, können Sie die get-Methode verwenden.

randomElement.get // This will return a String (or a NotSuchElementExeption)

Dennoch werden Mustervergleich oder getOrElse empfohlen:

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. 

Beachten Sie dass die randomChoice-Methode die Ersetzung von Elementen annimmt. 

Wir können auch etwas Sicherheit mit der Monde Option hinzufügen (mit der Funktion lift und einer Bedingung).

Wenn Sie diese Funktion für Arrays verwenden (die möglicherweise leer sind), ist Ihr Ergebnis immer eine Option.

Referenztransparenz FTW\o /

def getRandElemO[T](arr: Array[T]): Option[T] =
  if (arr.isEmpty) None
  else arr lift util.Random.nextInt(arr.length)
0

Eine bessere Antwort, bei der das Array überhaupt nicht neu gemischt wird, wäre folgende:

import scala.util.Random

object sample {
  //gets random element from array
  def arr[T](items:Array[T]):T = {
    items(Random.nextInt(items.length))
  }
}

Dies funktioniert auch generisch 

0
Josh Weinstein