【发布时间】:2015-09-24 19:38:17
【问题描述】:
我想在保持顺序的同时从非常大的列表中随机抽取样本。我写了下面的脚本,但是它需要.map(idx => ls(idx)),这非常浪费。我可以看到一种通过辅助函数和尾递归来提高效率的方法,但我觉得必须有一个更简单的解决方案,我错过了。
有没有一种干净且更有效的方法来做到这一点?
import scala.util.Random
def sampledList[T](ls: List[T], sampleSize: Int) = {
Random
.shuffle(ls.indices.toList)
.take(sampleSize)
.sorted
.map(idx => ls(idx))
}
val sampleList = List("t","h","e"," ","q","u","i","c","k"," ","b","r","o","w","n")
// imagine the list is much longer though
sampledList(sampleList, 5) // List(e, u, i, r, n)
编辑:
看来我不清楚:我指的是保持值的顺序,而不是原始的 List 集合。
【问题讨论】:
-
使用
Vector而不是List- 它是一棵宽树,所以随机访问是 O(log n)。 -
谢谢
lmm,但我需要它是一个列表,因为我应用于此集合的大多数其他操作在它是一个列表时效果最好。 -
真的吗?没有多少可以作为列表更好地工作(其中大部分是由于结构共享,鉴于您想重复随机抽样,这似乎不太可能)。所以我同意 Vector 似乎是更好的选择
-
如果您愿意采集不是特定大小而是近似百分比的样本,您可以使用平面图和随机数生成器在 O(n) 时间内完成。
标签: performance list scala random