2016-11-23 74 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非空時纔會執行。

相關問題