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?
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"))
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".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With