Например, есть массив Scala val A = Array("please", "help", "me")
. Как выбрать случайный элемент из этого массива?
Как выбрать случайный элемент из массива в Scala?
Ответы (6)
Мы также можем добавить немного безопасности с помощью монады Option
(используя метод lift
)
Фактически, при использовании этого метода в любой коллекции, даже если ваша коллекция пуста или ваш случайный индекс выходит за границы, вашим результатом всегда будет Option.
Безопасное вождение ‹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)))
Лучшим ответом, который вообще не требует перетасовки массива, будет следующий:
import scala.util.Random
object sample {
//gets random element from array
def arr[T](items:Array[T]):T = {
items(Random.nextInt(items.length))
}
}
Это также работает в целом
Если вам нужно более идиоматическое решение, рассмотрите возможность использования шаблона классов типов (неявные классы в 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)))
}
Теперь, если неявный класс находится в области видимости, вы можете:
val randomElement: Option[String] = List("this", "is", "a", "list").getRandomElement
Если вы уверены, что параметр содержит какое-то значение, вы можете использовать метод get
.
randomElement.get // This will return a String (or a NotSuchElementExeption)
Тем не менее рекомендуется сопоставление с образцом или getOrElse
:
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.
Обратите внимание, что метод randomChoice
предполагает замену элементов.
A.length
равно нулю. Никогда не забывайте о крайних случаях
- person George Pligoropoulos; 11.06.2014
headOption
, поскольку Seq
(здесь Array
) может быть пустым.
- person Colin Woodbury; 01.08.2014
A.size
равно нулю. Никогда не забывайте о крайних случаях
- person George Pligoropoulos; 11.06.2014
A.lift(Random.nextInt(A.size))
, что даст вам Option[Int]
- person Jon Onstott; 06.04.2015
A.size
равно 0
- person 7kemZmani; 14.02.2018