【发布时间】:2013-08-21 09:58:49
【问题描述】:
我目前正在这样做:(repeatedly n #(rand-nth (seq coll))),但我怀疑可能有更惯用的方式,原因有两个:
- 我发现使用短匿名函数通常有更简洁和更具表现力的替代方法,例如
partial -
repeatedly的文档字符串说“可能有副作用”,暗示它不打算用于产生值
我想我可以找到一种使用 reduce 的方法,但这似乎很棘手且效率较低,因为它必须处理整个集合,因为 reduce 并不懒惰。
【问题讨论】:
-
如果你想要可能的重复,你的代码是可以的,except你可以考虑使用向量而不是序列,这样你就不会为每个@987654326 产生线性时间查找@.
-
请注意,关于“可能有副作用”的部分适用于此。对
rand-nth的调用具有改变随机数生成器状态的副作用。如果没有副作用,那么每次调用都会返回相同的结果,因此您可能不需要多次调用它。 -
“可能有副作用”并不意味着它不应该被用来产生价值。它只是暗示如果您的函数是纯函数(没有副作用),那么您将获得 n 倍相同的值。所以
repeatedly仅在函数不是纯函数时才有用 - 并且 rand fns 不是纯函数,因此您的代码一切正常。 -
您的代码有问题:您在 coll 上调用
seq,从而将 coll 按顺序转换。这意味着nth现在将需要线性时间(count也有可能)。在一个大集合上,它会大大降低性能。最好转换为向量(使用vec)并将结果向量提升出闭包(以免每次都转换它)。一种提升方法是使用旧的let。另一种是使用partial。(repeatedly n (partial rand-nth (vec coll))) -
@cgrand 有见地,谢谢!!