Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: how to update multiple values in a map

Tags:

clojure

I have a map that have multiple counters in it, for example:

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

I would like to increase counter2 by one, and reset counter1 and counter3 to zero.

I can not seem to think of a way to do it. The best I have come across is the below function. But, this function does not reset counter1 and counter3 back to zero, it just does not increment them.

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

Is it possible to do what I am asking with a single swap!, or do I need to implement with a call to swap! and multiple reset!

like image 889
sakh1979 Avatar asked Nov 14 '15 22:11

sakh1979


2 Answers

Or separate the two operations:

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

edit

In case you are on an < 1.7 Clojure version, use update-in instead of update

like image 134
cfrick Avatar answered Sep 24 '22 15:09

cfrick


Keep it simple! Use a normal merge and access :counter2 again from the map.

(swap! m1 (fn [m]
            (merge m {:counter1 0
                      :counter2 (-> m :counter2 inc)
                      :counter3 0})))
like image 28
TheQuickBrownFox Avatar answered Sep 25 '22 15:09

TheQuickBrownFox