在Clojure中更新层次结构/树结构

时间:2014-03-09 19:23:43

标签: clojure tree

我有一个Atom,比如x:

(def x (atom {:name "A" 
              :id 1 
              :children [{:name "B"
                          :id 2 
                          :children []} 
                         {:name "C"
                          :id 3 
                          :children [{:name "D" :id 4 :children []}]}]}))

需要更新子图,例如:

if :id is 2 , change :name to "Z"

导致更新的Atom:

{:name "A" 
 :id 1 
 :children [{:name "Z"
             :id 2
             :children []} 
            {:name "C"
             :id 3 
             :children [{:name "D" :id 4 :children []}]}]}

怎么办呢?

2 个答案:

答案 0 :(得分:1)

您可以使用postwalk命名空间中的prewalkclojure.walk来执行此操作。

(def x (atom {:name "A" 
              :id 1 
              :children [{:name "B"
                          :id 2 
                          :children []} 
                         {:name "C"
                          :id 3 
                          :children [{:name "D" :id 4 :children []}]}]}))
(defn update-name [x]
  (if (and (map? x) (= (:id x) 2))
    (assoc x :name "Z")
    x))

(swap! x (partial clojure.walk/postwalk update-name))

答案 1 :(得分:1)

您还可以使用clojure.zip命名空间

中的 Zippers

在此处找到一个有效的示例https://gist.github.com/renegr/9493967