更新包含在原子内的Clojure贴图

时间:2015-04-06 11:46:20

标签: 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}}

任何帮助都会很棒

1 个答案:

答案 0 :(得分:3)

您正在使用新值替换旧值(使用assoc)。您正在寻找的是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}}