在clojure中如何实现具有嵌套返回的循环? [英] how would a loop with a nested return be implemented in clojure?
问题描述
我在这里玩一个狡猾的教程:
I'm playing around with a crafty tutorial here:
http://buildnewgames.com/introduction-to-crafty/
我想知道如何在Clojurescript / clojure
and am wondering how this particular function be implemented in clojurescript/clojure
var max_villages = 5;
for (var x = 0; x < Game.map_grid.width; x++) {
for (var y = 0; y < Game.map_grid.height; y++) {
if (Math.random() < 0.02) {
Crafty.e('Village').at(x, y);
if (Crafty('Village').length >= max_villages) {
return;
}
}
}
}
知道我们可以有(for [])
构造,但是当max_villages命中5时如何让它停止?
I know that we can have the (for [])
construct but how would you get it to stop when max_villages hits 5?
推荐答案
这里有一种方法:
(def max-villages 5)
(->> (for [x (range map-width)
y (range map-height)]
[x y])
(filter (fn [_] (< (rand) 0.02)))
(take max-villages))
然后可能添加(map make-village-at)
或类似的下一阶段的管道;如果它的意图是执行副作用,添加 dorun
或 doall
作为最后阶段,迫使他们立即发生(根据返回值是否有趣,选择一个)。
Then perhaps add (map make-village-at)
or something similar as the next stage of the pipeline; if it's meant to perform side effects, add a dorun
or doall
as the final stage to force them to happen at once (choosing one or the other depending on whether the return values are interesting).
注意。
使用计数器进行比较的更强制的方法:
A more imperative approach with a counter for comparison:
(let [counter (atom 0)]
(doseq [x (range map-width)
:while (< @counter max-villages)
y (range map-height)
:while (< @counter max-villages)
:when (< (rand) 0.02)]
(swap! counter inc)
(prn [x y]))) ; call make-village-at here
:while
当其测试表达式失败时,在当前嵌套级别终止循环; :当
立即移动到下一个迭代。 doseq
也支持分块,但:while
将阻止它执行不必要的工作。
:while
terminates the loop at the current nesting level when its test expression fails; :when
moves on to the next iteration immediately. doseq
supports chunking too, but :while
will prevent it from performing unnecessary work.
这篇关于在clojure中如何实现具有嵌套返回的循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!