Reputation: 2177
Given the following scenario:
(defrecord Person [firstname lastname])
(def some-map (ref {}))
(dosync
(alter some-map conj {1 (Person. "john" "doe")})
(alter some-map conj {2 (Person. "jane" "jameson")}))
To change the firstname of "joe" to "nick", I do the following:
(dosync
(alter some-map (fn [m]
(assoc m 1
(assoc (m 1) :firstname "nick")))))
What is the idiomatic way of doing this in Clojure?
Upvotes: 6
Views: 1701
Reputation: 45081
Edit: For your example assoc-in
is better, since you ignore the previous value. Keeping this answer for cases where you actually need the previous value:
The update-in
is there to update nested structures:
(alter some-map update-in [1 :firstname] (constantly "nick"))
The last argument is a function on the value to be "replaced" (like assoc
, it does not replace but returns a new structure.) In this case the old value is ignored, hence the constantly
function that always returns "nick".
Upvotes: 2
Reputation: 17773
No need to use update-in, for this case, assoc-in is exactly what you want.
(dosync (alter some-map assoc-in [1 :firstname] "nick"))
Upvotes: 5