更新Clojure中的层次/树结构

更新Clojure中的层次/树结构,clojure,tree,Clojure,Tree,我有一个原子,像x: (def x (atom {:name "A" :id 1 :children [{:name "B" :id 2 :children []} {:name "C" :id 3

我有一个原子,像x:

(def x (atom {:name "A" 
              :id 1 
              :children [{:name "B"
                          :id 2 
                          :children []} 
                         {:name "C"
                          :id 3 
                          :children [{:name "D" :id 4 :children []}]}]}))
需要更新submap,例如:

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 []}]}]}
如何做到这一点?

您可以使用名称空间或从名称空间中执行

(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))

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


在此处查找工作示例

将更新拆分为一个函数,返回新映射:(defn update nested map[search key search val add map nm]“查找包含搜索键search val的映射,并将此映射与add map合并。”(postwalk(fn[x](if(and(map?x))(=(search key x)搜索值(val))(合并x添加地图)x))nm)