2015-04-06 25 views
0

我試圖更新原子內的地圖。每個映射都由一個值引用。更新包裹在原子內的Clojure地圖

(def a (atom {})) 

(defn foo [id mps] 
    (let [x (merge (get mps id) mps)] 
    (swap! a assoc id x) x)) 

(foo 2 {:baz 88}) => {:baz 88} 

@a => {2 {:baz 88}} 

(foo 2 {:bar 99}) => {:bar 99} ?? 

@a => {2 {:bar 99}} ?? 

它似乎是覆蓋地圖而不是更新它。我要尋找的結果是:

(foo 2 {:baz 88}) => {:baz 88} 

@a => {2 {:baz 88}} 

(foo 2 {:bar 99}) => {:bar 99, :baz 88} 

@a => {2 {:bar 99, :baz 88}} 

任何幫助(使用assoc)是偉大的

回答

3

你用新的替換舊的值。你正在尋找的是直接在原子上的merge-withhttp://conj.io/store/v1/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/merge-with/)的行爲。像:

user=> (def a (atom {})) 
#'user/a 
user=> (swap! a #(merge-with merge % {:a {:b 1}})) 
{:a {:b 1}} 
user=> (swap! a #(merge-with merge % {:a {:c 2}})) 
{:a {:c 2, :b 1}} 
+0

你先生是男人..謝謝 – adebesin 2015-04-06 16:04:41

+0

'assoc-in'應該也能工作。它創建所有不存在的鍵。 – ClojureMostly 2015-04-07 00:46:49