2015-08-15 45 views
1

我有一個嵌套的減少功能,我會哄名爲反原子每一個條件滿足時遞增計數Clojure的 - 從原子重構爲不可變的

(defrecord TreeNode [val left right]) 

(defn build-tree [node xs] 
    (let [counter (atom 1)] 
    (reduce (fn [t x] 
      (reduce (fn [t l] 
         (if-not (= (:val l) -1) 
         (let [next-branch (nth xs @counter)] 
          (swap! counter inc) 
          ;; do stuff 
          ) t) 
         )t (map-indexed 
          (fn [idx itm] 
          (let [side (if (= 0 idx) :left :right)] 
           {:side side :index idx :val itm})) x))) node xs))) 

我並不喜歡使用可變裁判在函數中。有沒有一種方法可以在不使用ref的情況下實現相同的行爲?

回答

2
;; for starters, we can pass the counter through each reduce 
(defn build-tree [node xs] 
    (let [[counter tree] (reduce (fn [[counter tree] x] 
           (reduce (fn [[counter' t] l] 
              (if-not (= (:val l) -1) 
              (let [next-branch (nth xs counter) 
                ... ... 
                t' ...] 
               [(inc counter') t']) 
              [counter' t]) 
              [counter t] 
              (map-indexed 
              (fn [idx itm] 
               (let [side (if (= 0 idx) :left :right)] 
               {:side side :index idx :val itm})) 
              x)))) 
           [0 node] 
           xs)])) 

;; the code becomes much clearer with apropriate let bindings 
(defn build-tree 
    [node xs] 
    ;; the optional name arg to an anonymous function makes stack traces much easier to read 
    (let [process-branch (fn process-branch [[counter t] l] 
         (if-not (= (:val l) -1) 
          (let [next-branch (nth xs counter) 
           ... ... 
           t' ...] 
          [(inc counter) t']) 
          [counter t])) 
     mark-branch (fn mark-branch [x] 
         (map-indexed 
         (fn [idx itm] 
         (let [side (if (= 0 idx) :left :right)] 
          {:side side :index idx :val itm})) 
         x)) 
     [counter tree] (reduce (fn [[counter tree] x] 
           (reduce process-branch 
             [counter t] 
             (mark-branch x))) 
           [0 node] 
           xs)] 
    tree)) 
+0

什麼做單引號的意思是[(INC計數器「)T」] – dagda1

+0

'counter''和't''是綁定的名字,緊接着命名,如數學約定。 'x','x'','x''等等,其中'''表示序列中的「下一個值」 – noisesmith