不得不说我大约两周前就开始学习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"
。
我试过很多像assoc
,update-in
等等的东西,但没有任何作用。
我怎么做我的东西? 非常感谢你!
答案 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”。