Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Clojure中是否有更惯用的方法获取集合的N个随机元素?_Clojure_Idioms - Fatal编程技术网

在Clojure中是否有更惯用的方法获取集合的N个随机元素?

在Clojure中是否有更惯用的方法获取集合的N个随机元素?,clojure,idioms,Clojure,Idioms,我现在这样做:(重复n#(rand nth(seq coll)),但我怀疑可能有一种更惯用的方式,原因有二: 我发现,除了使用简短的匿名函数外,还有一种更简洁、更具表现力的替代方法,例如partial 的docstring反复显示“可能有副作用”,这意味着它不打算用于生成值 我想我可以找到一种使用reduce的方法,但这似乎很棘手,效率较低,因为它必须处理整个集合,因为reduce并不懒惰。对于大型集合来说,一个简单但不是最佳的解决方案可能是: (take n (shuffle coll))

我现在这样做:
(重复n#(rand nth(seq coll))
,但我怀疑可能有一种更惯用的方式,原因有二:

  • 我发现,除了使用简短的匿名函数外,还有一种更简洁、更具表现力的替代方法,例如
    partial

  • 的docstring反复显示“可能有副作用”,这意味着它不打算用于生成值

我想我可以找到一种使用
reduce
的方法,但这似乎很棘手,效率较低,因为它必须处理整个集合,因为
reduce
并不懒惰。

对于大型集合来说,一个简单但不是最佳的解决方案可能是:

(take n (shuffle coll))

具有不重复元素的“优势”。你也可以实现一个延迟洗牌,但它会涉及更多的代码。

我知道这并不完全是你想要的-但是如果你做了大量的采样和统计工作,你可能会对白炽灯感兴趣(
[白炽灯“1.5.2”]
)。 白炽灯提供功能
sample
,提供样本大小和更换选项

(require '[incanter.stats :refer [sample]]))

(sample [1 2 3 4 5 6 7] :size 5 :replacement false) 
; => (1 5 6 2 7)

如果你想要可能的重复,你的代码是可以的,除了你可以考虑使用向量而不是一个序列,这样你就不会对每个<代码> NTH <代码>产生线性时间查找。调用
rand nth
会产生改变随机数生成器状态的副作用。如果没有副作用,那么每个调用都将返回相同的结果,因此您可能不需要多次调用它。“可能有副作用”并不意味着不应该使用它来生成值。它只是暗示,如果你的函数是纯函数(没有副作用),那么你将得到n倍的相同值。因此,
反复
仅在函数不纯净时才有用,而rand fns不纯净,因此代码一切正常。但代码有问题:在coll上调用
seq
,从而按顺序打开coll。这意味着
nth
现在需要线性时间(而且
count
也可能需要线性时间)。在一个大的集合上,它会大大降低性能。最好转换为向量(使用
vec
),并将生成的向量从闭包中取出(这样就不会每次都转换它)。将其吊出的一种方法是使用一个好的旧
let
。另一种是使用
partial
<代码>(重复n(部分兰特n(vec科尔))
@cgrand insightful,谢谢!!