2016-11-23 75 views
1

我有这样的数据结构:为什么在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) 

但是,当我这样做,其超时或崩溃我的电脑...我做错了什么?

回答

2

if形式应该是这样的:

(if conditional-expr true-expr false-expr) 

false-expr实际上是可选的,用的nil默认值,如果它离开了,但我不认为这是你想要的。它看起来像你想回到retnodes是空的,否则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非空时才会执行。

相关问题