如何从 Smalltalk 中的集合中获取特定数量的随机元素?
How to get a specific number of random elements from a collection in Smalltalk?
如何优雅地从集合中获取特定数量 (>1) 个不同的随机元素?
这是我认为或多或少看起来不错,但效率不高的东西:
yourCollection asSet asOrderedCollection shuffled first: numberOfElements
考虑以下代码片段
sample: anInteger from: aCollection using: aGenerator
| sample |
sample := Set new: anInteger.
[sample size = anInteger]
whileFalse: [ | element |
element := aCollection atRandom: aGenerator.
sample add: element].
^sample asArray
一些备注
显式生成器:它显式使用给定的生成器,即 Random
的实例,我称之为 aGenerator
.出于数学原因,如果您正在为您的应用程序获取样本,那么所有这些样本都应该在您的程序中使用完全相同的生成器。此外,这会给您带来额外的好处:保存并稍后恢复 seed
,您将能够重现系统以前的 "random" 行为,这对测试很有用。
不检查可用性:代码不检查是否可以获得所需的样本,如果aCollection
没有至少 anInteger
个不同的元素。
无类代码:方法应该去一些class.
例如:
Random >> sample: anInteger from: aCollection
| sample |
sample := Set new: anInteger.
[sample size = anInteger]
whileFalse: [ | element |
element := aCollection atRandom: self.
sample add: element].
^sample asArray
更新
这是另一种方法:
Random >> remove: anInteger from: aCollection
| sample |
sample := OrderedCollection new: anInteger.
anInteger timesRepeat: [| index element |
index := aCollection size atRandom: self.
element := aCollection removeAt: index.
sample add: element].
^sample
评论
通常情况下,当我们想要不重复地采样时,我们也想在随机选择元素时从集合中删除元素。在这些情况下,经常发生的是集合已知没有重复。
如何优雅地从集合中获取特定数量 (>1) 个不同的随机元素?
这是我认为或多或少看起来不错,但效率不高的东西:
yourCollection asSet asOrderedCollection shuffled first: numberOfElements
考虑以下代码片段
sample: anInteger from: aCollection using: aGenerator
| sample |
sample := Set new: anInteger.
[sample size = anInteger]
whileFalse: [ | element |
element := aCollection atRandom: aGenerator.
sample add: element].
^sample asArray
一些备注
显式生成器:它显式使用给定的生成器,即
Random
的实例,我称之为aGenerator
.出于数学原因,如果您正在为您的应用程序获取样本,那么所有这些样本都应该在您的程序中使用完全相同的生成器。此外,这会给您带来额外的好处:保存并稍后恢复seed
,您将能够重现系统以前的 "random" 行为,这对测试很有用。不检查可用性:代码不检查是否可以获得所需的样本,如果
aCollection
没有至少anInteger
个不同的元素。无类代码:方法应该去一些class.
例如:
Random >> sample: anInteger from: aCollection
| sample |
sample := Set new: anInteger.
[sample size = anInteger]
whileFalse: [ | element |
element := aCollection atRandom: self.
sample add: element].
^sample asArray
更新
这是另一种方法:
Random >> remove: anInteger from: aCollection
| sample |
sample := OrderedCollection new: anInteger.
anInteger timesRepeat: [| index element |
index := aCollection size atRandom: self.
element := aCollection removeAt: index.
sample add: element].
^sample
评论
通常情况下,当我们想要不重复地采样时,我们也想在随机选择元素时从集合中删除元素。在这些情况下,经常发生的是集合已知没有重复。