如何从 Scala 的数组中选择一个随机元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5051574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:49:56  来源:igfitidea点击:

How to choose a random element from an array in Scala?

scalascala-2.8

提问by sam

For example, there is a Scala array val A = Array("please", "help", "me"). How to choose a random element from this array?

例如,有一个 Scala 数组val A = Array("please", "help", "me")。如何从这个数组中选择一个随机元素?

采纳答案by topless

import java.util.Random
// ...
val rand = new Random(System.currentTimeMillis())
val random_index = rand.nextInt(A.length)
val result = A(random_index)

回答by user1338062

import scala.util.Random

val A = Array("please", "help", "me")
Random.shuffle(A.toList).head

回答by ahogue

import scala.util.Random

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

回答by Raphael Bobillot

We can also add some safety with the Optionmonad (using the liftfunction, and a condition)

我们还可以为Optionmonad添加一些安全性(使用lift函数和条件)

Actually, if you use this function on Arrays (that could be empty), your result will always be an Option.

实际上,如果您在数组(可能为空)上使用此函数,您的结果将始终是一个选项。

Referencial Transparency FTW \o/

参考透明度 FTW \o/

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

回答by Rodrigo Hernández Mota

If you want a more idiomatic solution, consider using the typeclass pattern (implicit classes in scala).

如果您想要更惯用的解决方案,请考虑使用 typeclass 模式(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 getmethod.

如果您确定该选项包含某个值,则可以使用该get方法。

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

Nonetheless, pattern matching or getOrElseare recommended:

尽管如此,还是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. 

Notethat the randomChoicemethod assumes substitution of elements.

请注意,该randomChoice方法假定元素替换。

回答by Josh Weinstein

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

这也适用于一般情况