Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update the values of multiple keys

Tags:

clojure

If you have a map or a collection of maps and you'd like to be able to update the values of several keys with one function, what the the most idiomatic way of doing this?

=> (def m [{:a 2 :b 3} {:a 2 :b 5}])
#'user/m
=> (map #(update-in % [:a] inc) m)
({:a 3, :b 3} {:a 3, :b 5})

Rather than mapping update-in for each key, I'd ideally like some function that operates like this:

=> (map #(update-vals % [:a :b] inc) m)
({:a 3, :b 4} {:a 3, :b 6})

Any advice would be much appreciated! I'm trying to reduce the number of lines in an unnecessarily long script.

like image 906
Giles Avatar asked Mar 09 '12 17:03

Giles


1 Answers

Whenever you need to iteratively apply a fn to some data, reduce is your friend:

(defn update-vals [map vals f]
  (reduce #(update-in % [%2] f) map vals))

Here it is in action:

user> (def m1 {:a 2 :b 3})
#'user/m1
user> (update-vals m1 [:a :b] inc)
{:a 3, :b 4}
user> (def m [{:a 2 :b 3} {:a 2 :b 5}])
#'user/m
user> (map #(update-vals % [:a :b] inc) m)
({:a 3, :b 4} {:a 3, :b 6})
like image 60
Mike Thvedt Avatar answered Oct 07 '22 10:10

Mike Thvedt