我有这个数据结构:
(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)
但是当我这样做时,它会超时或者崩溃我的电脑......我做错了什么?
答案 0 :(得分:2)
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
非空时执行。