不得不说我大约两周前就开始学习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"}
}
Run Code Online (Sandbox Code Playgroud)
并需要:team "X"
改为:team "H"
.我尝试了许多类似的东西assoc
,update-in
但没有任何作用.
我怎么能做我的东西?非常感谢!
Nie*_*lsK 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"}}
Run Code Online (Sandbox Code Playgroud)
但是,如果你想要更新所有团队"X",无论具体路径如何,在树的所有递归级别上,你都可以使用clojure.walk的prewalk或postwalk函数结合你自己的函数:
(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"}}
Run Code Online (Sandbox Code Playgroud)
det*_*erb 12
步行功能很适合这样更换.
(clojure.walk/prewalk-replace {[:team "X"] [:team "H"]} map)
传入向量可以确保您不仅仅替换所有"X".