为什么在Clojure中重复使用会导致崩溃?
问题描述:
我有这样的数据结构:为什么在Clojure中重复使用会导致崩溃?
(def initial-map {:name "Root"
:children [{:name "Child1" :children [{:name "Grandchild1"}]}
{:name "Child2"}
{:name "Child3"}]})
,我需要把它弄成这个样子:
[["Root" 0] ["Child1" 1] ["Child2" 1] ["Child3" 1] ["Grandchild1" 2]]
凡数字表示在数据结构中的节点的深度。
我已经写了这个功能,试图从第一到第二:
(defn node-xform [ret nodes depth]
(if empty? nodes)
ret
(recur (conj ret (map #(vector (:name %) depth) nodes))
(flatten (map #(:children %) nodes))
(inc depth)))
和我叫它这样
(node-xform [] (vector initial-map) 0)
但是,当我这样做,其超时或崩溃我的电脑...我做错了什么?
答
的if
形式应该是这样的:
(if conditional-expr true-expr false-expr)
的false-expr
实际上是可选的,用的nil
默认值,如果它离开了,但我不认为这是你想要的。它看起来像你想回到ret
时nodes
是空的,否则recur
:
(defn node-xform [ret nodes depth]
(if (empty? nodes) ; <-- fixed this line
ret
(recur (conj ret (map #(vector (:name %) depth) nodes))
(flatten (map #(:children %) nodes))
(inc depth)))) ; <-- added another close-paren here for the "if"
我没有实际测试,看看是否能返回你期望的答案,但至少会干掉你的无限递归问题。
你的代码产生一个无限循环,因为node-xform
总是执行recur
形式,这将导致无限尾递归。更正if
表单的语法使得recur
表达式仅在nodes
非空时才会执行。