How to update ref map entries in Clojure?

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 first name "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 to do this in Clojure?

+6
source share
2 answers

No need to use update-in, for this case the binding is exactly what you want.

(dosync (alter some-map assoc-in [1 :firstname] "nick"))

+5
source

Edit: for your example, assoc-in better since you are ignoring the previous value. Keeping this answer for cases when you really need the previous value:

update-in there is the possibility of updating nested structures:

 (alter some-map update-in [1 :firstname] (constantly "nick")) 

The last argument is the function for the value to be replaced (for example, assoc , it does not replace, but returns a new structure.) In this case, the old value is ignored, therefore, the function is constantly , which always returns "nick".

+2
source

Source: https://habr.com/ru/post/923126/


All Articles