Clojure: Apply a Function To Each Value of a Map
Join the DZone community and get the full member experience.
Join For FreeI recently needed to update all of the values of map, and couldn't find an individual function in clojure.core that did the trick. Luckily, implementing an update-values function is actually very straightforward. The following function reduces the original map to a new map with the same elements, except the values are all the result of applying the specified function and any additional args.
(defn update-values [m f & args] (reduce (fn [r [k v]] (assoc r k (apply f v args))) {} m))The code is concise, but perhaps a bit terse. Still, it does the trick, as the REPL session below demonstrates.
Clojure 1.2.0 user=> (defn update-values [m f & args] (reduce (fn [r [k v]] (assoc r k (apply f v args))) {} m)) #'user/update-values user=> (update-values {:a 1 :b 2 :c 3} inc) {:c 4, :b 3, :a 2} user=> (update-values {:a 1 :b 2 :c 3} + 10) {:c 13, :b 12, :a 11} user=> (update-values {:a {:z 1} :b {:z 1} :c {:z 1}} dissoc :z) {:c {}, :b {}, :a {}}The last example is the specific problem I was looking to solve: remove a key-value pair from all the values of a map. However, the map I was working with actually had a bit of nesting. Let's define an example map that is similar to what I was actually working with.
user=> (def data {:boxes {"jay" {:linux 2 :win 1} "mike" {:linux 2 :win 2}}}) #'user/dataEasy enough, I have 2 linux boxes and 1 windows box, and Mike has 2 linux and 2 windows. But, now the company decides to discard all of our windows boxes, and we'll need to update each user. A quick combo of update-in with update-values does the trick.
user=> (update-in data [:boxes] update-values dissoc :win) {:boxes {"mike" {:linux 2}, "jay" {:linux 2}}}As you can see, the update-values function plays nice with existing Clojure functions as well.
Disclosure: I am long AAPL and own every device Apple puts out. Don't take my example numbers to literally. Also, much to my dismay, DRW has yet to discard all of our windows boxes.
From http://blog.jayfields.com/2011/08/clojure-apply-function-to-each-value-of.html
Clojure
Opinions expressed by DZone contributors are their own.
Trending
-
Security Challenges for Microservice Applications in Multi-Cloud Environments
-
Auto-Scaling Kinesis Data Streams Applications on Kubernetes
-
Merge GraphQL Schemas Using Apollo Server and Koa
-
13 Impressive Ways To Improve the Developer’s Experience by Using AI
Comments