【问题标题】:How to return multiple random elements from List scala如何从List scala返回多个随机元素
【发布时间】:2014-01-28 09:52:15
【问题描述】:

如何从 List 返回多个随机元素。

这个问题How to choose a random element from an array in Scala?指的是使用:

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

我的可变性认为我可以创建一个 for 循环并继续选择下一个随机元素(不包括已选择的元素)并将其添加到新列表中。在 Scala 中是否有更惯用/更实用的方式来实现这一点?

【问题讨论】:

  • Random.shuffle(A.toList).take(n)
  • "take" 使用循环实现这一点。可能是性能原因。
  • @HappyCoder:是的,Random.shuffle(A.toIndexedSeq).take(n) 更好。

标签: scala


【解决方案1】:

head 方法将返回列表的第一个元素,但 take(n) 将返回列表前面的最多 n 个元素。所以在你洗牌后,只需使用take

def takeRandomN[A](n: Int, as: List[A]) =
  scala.util.Random.shuffle(as).take(n)

如果您的列表 asn 短,那么这将简单地改变 as

对于您只想要一小部分子集的大型列表,这似乎会很慢,但随机子集可能会从列表中统一采样,因此无论如何您都必须遍历整个内容.对于Array 或其他随机访问的结构,您可以做得更好,但对于List,您不能。

【讨论】:

  • 请注意,这对于小型列表来说很好,但对于大型列表,您想要一个小的随机子集可能会非常缓慢。
  • @Shawn 出于好奇,什么对大列表/集合有效?
  • 随机播放是 O(n)。我不确定你能否做得更好。
【解决方案2】:

更“保守”的变体,不使用 mutables/vars。只是为了锻炼:

def takeRandomFrom[T](n: Int, list: List[T]): List[T] = {
  @tailrec
  def innerTake(n:Int, list: List[T], result: List[T]): List[T] = {
    if (n == 0 || list.isEmpty) {
  result
} else {
  innerTake(n - 1, list.tail, list.head :: result)
}
  }

  innerTake(n, Random.shuffle(list), Nil)
}  

takeRandomFrom(2, Array("please", "help", "me").toList)

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 2020-07-19
    • 2013-04-26
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 2017-07-22
    • 2011-06-30
    相关资源
    最近更新 更多