Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Clojure update-in with multiple keys

Tags:

map

clojure

I'm trying to apply a function to all elements in a map that match a certain key.

(def mymap {:a "a" :b "b" :c "c"}) 
(update-in mymap [:a :b] #(str "X-" %))

I'm expecting

{:a "X-a", :c "c", :b "X-b"}

But I get

ClassCastException java.lang.String cannot be cast to clojure.lang.Associative clojure.lang.RT.assoc (RT.java:702)

Anyone can help me with this?

like image 783
Machiel Avatar asked Mar 27 '13 06:03

Machiel


2 Answers

update-in is to update a single key in the map (at a particular nesting level, [:a :b] means update key :b inside the map value of key :a.

What you want can be done using reduce:

(reduce #(assoc %1 %2 (str "X-" (%1 %2)))
        mymap
        [:a :b])
like image 69
Ankur Avatar answered Oct 24 '22 06:10

Ankur


Here's a generalized function:

(defn update-each
  "Updates each keyword listed in ks on associative structure m using fn."
  [m ks fn]
  (reduce #(update-in %1 [%2] fn) m ks))

(update-each mymap [:a :b] #(str "X-" %))
like image 2
Brad Koch Avatar answered Oct 24 '22 05:10

Brad Koch