如何在clojure中实现具有嵌套返回的循环?
我在这里玩一个狡猾的教程: 我想知道如何在clojurescript/clojure中实现这个特殊的功能如何在clojure中实现具有嵌套返回的循环?,clojure,clojurescript,Clojure,Clojurescript,我在这里玩一个狡猾的教程: 我想知道如何在clojurescript/clojure中实现这个特殊的功能 var max_=5; 对于(var x=0;x
var max_=5;
对于(var x=0;x=最大村庄){
返回;
}
}
}
}
我知道我们可以使用(for[])
构造,但是当max_villages达到5时,如何让它停止呢?这里有一种方法:
(def max-villages 5)
(->> (for [x (range map-width)
y (range map-height)]
[x y])
(filter (fn [_] (< (rand) 0.02)))
(take max-villages))
:当循环的测试表达式失败时,
在当前嵌套级别终止循环<代码>:当立即进入下一个迭代时doseq
也支持分块,但是:虽然
会阻止它执行不必要的工作。使用递归,它可能类似于:
(letfn [(op [x y]
(if (= (rand) 0.02)
(do
(village-at x y)
(if (>= (village-length) max-villages) true))))]
(loop [x 0 y 0]
(when (and (< x width) (not (op x y)))
(if (= (inc y) height)
(recur (inc x) 0)
(recur x (inc y))))))
(letfn[(op[x y]
(如果(=(兰特)0.02)
(做
(x y村)
(如果(>=(村庄长度)最大村庄数)为true))]
(循环[x0y0]
(当(和(
这是一个很棒的教程
Michael方法的一个变体(我刚刚对他的答案发表了评论,但我还没有足够的堆栈能力)是使用笛卡尔积,而不是嵌套for循环:
;; some stub stuff to get the example to run
(ns example.core
(:use clojure.math.combinatorics))
(def max-villages 5)
(def map-width 10)
(def map-height 10)
(defn crafty-e [x y z] (print z))
;; the example, note I use doseq rather than map to empasize the fact that the loop
;; is being performed for its side effects not its return value.
(doseq [coord (take max-villages
(filter
(fn [_] (< (rand) 0.02))
(cartesian-product (range map-width) (range map-height))))]
(crafty-e :village :at coord))
;;一些让示例运行的存根
(ns example.core)
(:使用clojure.数学.组合数学)
(def最大值5)
(def地图宽度10)
(def地图高度10)
(defn crafty-e[x y z](打印z))
;; 注意,在这个例子中,我使用doseq而不是map来放大循环
;; 正在针对其副作用而不是返回值执行。
(doseq[coord(以最大值为准)
(过滤器
(fn[41;](<(兰特)0.02))
(笛卡尔积(范围贴图宽度)(范围贴图高度))]
(狡猾的e:村庄:在合作社)
带有@计数器的版本将起作用,但不是出于您想要的原因::while
将只“跳过”当前的x
绑定并移动到下一个绑定,这意味着计数器需要为每个x
测试一次,即使它不再更改。对于较小的贴图宽度
,这很好,但是对于较大(或无限)宽度,这是一个严重的问题。@amalloy确实,x
需要自己的:while
!谢谢你发现了这个错误,我马上就修好。(编辑:完成;还修复了措辞。)有趣的是,SO的语法突出显示是否基于问号?似乎认为分号是comments@jozefg它使用了一些东西,但是是的,它使用了标签
;; some stub stuff to get the example to run
(ns example.core
(:use clojure.math.combinatorics))
(def max-villages 5)
(def map-width 10)
(def map-height 10)
(defn crafty-e [x y z] (print z))
;; the example, note I use doseq rather than map to empasize the fact that the loop
;; is being performed for its side effects not its return value.
(doseq [coord (take max-villages
(filter
(fn [_] (< (rand) 0.02))
(cartesian-product (range map-width) (range map-height))))]
(crafty-e :village :at coord))