2015-04-06 4 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}} 

Любая помощь будет большим

ответ

3

вы заменяете старое значение с новым (с использованием assoc). то, что вы ищете, - это поведение merge-with (http://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

+0

'assoc-in' должен работать. Он создает все несуществующие ключи. – ClojureMostly

Смежные вопросы