assoc-in用于替换或插入指定路径的地图中的值
(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的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"}}
(into {} (map (fn [[k v]] [k (inc v)]) {:a 1 :b 2})))
)。如果某物是等效的,它将替换它 - 无论它有多大。还要记住,您可以安全地使用任何Clojure数据结构作为映射中的键,这可能非常强大。 - deterbclojure.walk
覆盖了处理这种情况的最简单方法,在我找到它之前,我正在编写等效的代码。如果担心它不可用,当这种担忧实现时,我将使用在那里执行树遍历的策略 - 对于您的映射的主要结构将类似于(fn [f] (into {} (map (fn [[k v]] (if-let [result (transform k v)] result [k (f v)])
(请注意,这未经测试) - deterb