Clojure:如何更新地图中的多个值

时间:2015-11-14 22:45:03

标签: clojure

我有一个包含多个计数器的地图,例如:

(def m1 (atom {:counter1 10 :counter2 3 :counter3 11}))
;;;=> {:counter1 10, :counter3 11, :counter2 3}

我想将counter2加1,并将counter1和counter3重置为零。

我似乎无法想办法。我遇到的最好的是以下功能。但是,这个函数不会将counter1和counter3重置为零,它只是不会递增它们。

(swap! m1 (fn [m]
            (merge-with + m {:counter1 0
                             :counter2 1
                             :counter3 0})))
;;;=> {:counter1 10, :counter3 11, :counter2 4}

是否可以通过单次交换执行我要求的操作!或者我是否需要通过调用swap来实现!和多次重置!

3 个答案:

答案 0 :(得分:6)

或者分开两个操作:

(swap! m1 #(-> % 
           (update :counter2 inc) 
           (assoc :counter1 0 :counter3 0)))

修改

如果你在< 1.7 Clojure版本,使用update-in代替update

答案 1 :(得分:4)

保持简单!使用普通merge并再次从地图访问:counter2

(swap! m1 (fn [m]
            (merge m {:counter1 0
                      :counter2 (-> m :counter2 inc)
                      :counter3 0})))

答案 2 :(得分:1)

好吧,您可以修改代码来执行此操作,方法是将+内的merge-with替换为其他函数:

(defn my-plus [old new] (if (pos? new) (+ new old) 0))

我仍然在考虑解决它的不同方法。