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

发布于 2024-10-18 07:47:41 字数 91 浏览 1 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

新雨望断虹 2024-10-25 07:47:42

如果您想要更惯用的解决方案,请考虑使用 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)))
}

现在,如果隐式类在范围内,您可以:

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 方法假定元素替换。

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.

世界如花海般美丽 2024-10-25 07:47:42

根本不涉及重新排列数组的更好答案是这样的:

import scala.util.Random

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

这也通常有效

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

混浊又暗下来 2024-10-25 07:47:41
import scala.util.Random

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

val A = Array("please", "help", "me")
Random.shuffle(A.toList).head
一杯敬自由 2024-10-25 07:47:41
import scala.util.Random

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

val A = List(1, 2, 3, 4, 5, 6)
A(Random.nextInt(A.size))
江挽川 2024-10-25 07:47:41
import java.util.Random
// ...
val rand = new Random(System.currentTimeMillis())
val random_index = rand.nextInt(A.length)
val result = A(random_index)
import java.util.Random
// ...
val rand = new Random(System.currentTimeMillis())
val random_index = rand.nextInt(A.length)
val result = A(random_index)
清欢 2024-10-25 07:47:41

我们还可以使用 Option monad 添加一些安全性(使用 lift 方法)。

实际上,在任何集合上使用此方法时,
即使您的集合为空,或者您的随机索引超出范围,您的结果也将始终是一个选项。

安全驾驶<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)))

We 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)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文