Clojure嵌套地图 - 更改值

时间:2012-07-20 10:34:00

标签: map clojure key

不得不说我大约两周前就开始学习Clojure了,现在我整整三天都遇到了问题。

我有一张这样的地图:

{
  :agent1 {:name "Doe" :firstname "John" :state "a" :time "VZ" :team "X"}
  :agent2 {:name "Don" :firstname "Silver" :state "a" :time "VZ" :team "X"}
  :agent3 {:name "Kim" :firstname "Test" :state "B" :time "ZZ" :team "G"}
}

并需要将:team "X"更改为:team "H"。 我试过很多像assocupdate-in等等的东西,但没有任何作用。

我怎么做我的东西? 非常感谢你!

2 个答案:

答案 0 :(得分:18)

assoc-in用于替换或插入path

指定的映射中的值
(def m { :agent1 {:name "Doe" :firstname "John" :state "a" :time "VZ" :team "X"}
         :agent2 {:name "Don" :firstname "Silver" :state "a" :time "VZ" :team "X"}
         :agent3 {:name "Kim" :firstname "Test" :state "B" :time "ZZ" :team "G"}})

(assoc-in m [:agent1 :team] "H")

{:agent1 {:state "a", :team "H", :name "Doe", :firstname "John", :time "VZ"},
 :agent2 {:state "a", :team "X", :name "Don", :firstname "Silver", :time "VZ"},
 :agent3 {:state "B", :team "G", :name "Kim", :firstname "Test", :time "ZZ"}}

但是,如果您想要更新所有团队" X",无论特定路径如何,在树的所有递归级别上,您都可以使用clojure.walk的预走或后步行功能与您自己的功能相结合:

(use 'clojure.walk)
(defn postwalk-mapentry
    [smap nmap form]
(postwalk (fn [x] (if (= smap x) nmap x)) form))

(postwalk-mapentry [:team "X"] [:team "T"] m)

{:agent1 {:state "a", :team "T", :name "Doe", :firstname "John", :time "VZ"},
 :agent2 {:state "a", :team "T", :name "Don", :firstname "Silver", :time "VZ"},
 :agent3 {:state "B", :team "G", :name "Kim", :firstname "Test", :time "ZZ"}}

答案 1 :(得分:12)

步行功能很适合那样更换。

(clojure.walk/prewalk-replace {[:team "X"] [:team "H"]} map)

传入向量可以确保您不仅仅替换所有“X”。