如何在Scala中从数组中选择随机元素?
例如,有一个Scala数组如何在Scala中从数组中选择随机元素?,scala,scala-2.8,Scala,Scala 2.8,例如,有一个Scala数组vala=array(“请”、“帮助”、“我”)。如何从这个数组中选择一个随机元素?一个更好的答案是,根本不需要重新排列数组: import java.util.Random // ... val rand = new Random(System.currentTimeMillis()) val random_index = rand.nextInt(A.length) val result = A(random_index) import scala.util.Ra
vala=array(“请”、“帮助”、“我”)
。如何从这个数组中选择一个随机元素?一个更好的答案是,根本不需要重新排列数组:
import java.util.Random
// ...
val rand = new Random(System.currentTimeMillis())
val random_index = rand.nextInt(A.length)
val result = A(random_index)
import scala.util.Random
object sample {
//gets random element from array
def arr[T](items:Array[T]):T = {
items(Random.nextInt(items.length))
}
}
这也适用于一般情况我们还可以使用
选项
monad(使用提升
方法)增加一些安全性
实际上,在任何集合上使用此方法时,
即使您的集合为空,或者您的随机索引超出边界,您的结果也将始终是一个选项
如果你想要一个更惯用的解决方案,考虑使用Type CelpScript模式(Scala中的隐式类)。 现在,如果隐式类在范围内,您可以:
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.
注意随机选择方法假定替换元素 虽然这里的目的是不安全的伪随机性,但除非你真的,真的知道你在做什么,否则自我植入RNG是不好的做法。设置为“当前时间”尤其糟糕,因为它大大缩小了可能的种子窗口。有关更多信息,请参阅本系列:scala.util.Random具有shuffle,这非常简单,特别是当您需要多个随机元素时。请参阅下面的答案。如果
A.length
等于零,则此操作将崩溃。永远不要忘记边缘情况此边缘情况是需求中固有的。重新排列整个列表并选择头部是否比仅选择数组的O(1)值有效?这个问题没有具体说明任何效率需求,实际上给出了一个非常短的数组的示例:)为什么它应该是临时的?它可以工作,并且在数组边界中不太容易出现任何编码错误。应该是headOption
,因为Seq
(array
)可能是空的。A不是空的。它包含三个字符串。如果A.size
等于零,则会崩溃。永远不要忘记edge CaseSh,您可以使用A.lift(Random.nextInt(A.size))
它将为您提供选项[Int]
@JonOnstott如果A.size
是0考虑样本,也会崩溃。arr[Int](数组[Int]())请注意,它在技术上不是透明的,因为使用相同参数的两个调用不会给出相同的结果。要实现这一点,还必须在params中传递RNG实例。
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
randomElement.get // This will return a String (or a NotSuchElementExeption)
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.