Imagine you have a map like this:
(def person {
:name {
:first-name "John"
:middle-name "Michael"
:last-name "Smith" }})
What is the idiomatic way to change values associated with both :first-name and :last-name in one expression?
(Clarification: Let’s say you want to set :first-name to “Bob” and :last-name to “Doe”. Let’s also say that this map has some other values in it that we want to preserve, so constructing it from scratch is not an option)
Here are a couple of ways.
Edit
update-indoes recursiveassocs on your map. In this case it’s roughly equivalent to:The repetition of keys becomes more and more tedious as you go deeper into a series of nested maps.
update-in‘s recursion lets you avoid repeating keys (e.g.:name) over and over; intermediary results are stored on the stack between recursive calls. Take a look at the source for update-in to see how it’s done.associs dynamic (as areupdate-in,assoc-in, and most other Clojure functions that operate on Clojure data structures). Ifassoconto a map, it returns a map. If youassoconto a vector, it returns a vector. Look at the source for assoc and take a look in inRT.javain the Clojure source for details.