I have a structure that I created at the REPL,
{1 {10 {:id 101, :name "Paul"},
20 {}},
2 {30 {}, 40 {}},
3 {50 {}, 60 {}}}
and I want to add a new k v to the key 1, such that the resulting structure looks like this,
{1 {10 {:id 101, :name "1x2"}, 20 {}, 11 {:id 102, :name "Ringo"}},
2 {30 {}, 40 {}}, 3 {50 {}, 60 {}}}.
I just discovered get-in update-in and assoc-in for working with nested structures like these, but cannot figure out how to add new elements within elements. In my app this is all wrapped in a ref and updated with dosync/alter, but for now, I just want to be able to do this at the REPL.
Maybe I've just been looking at this too long, but any attempt to use assoc or assoc-in just changes what is already there, and does not append new elements.
Given your input
(def input
{1 {10 {:id 101 :name "Paul"}
20 {}}
2 {30 {} 40 {}}
3 {50 {} 60 {}}})
You can use assoc-in to add an element to the nested map with key 1 like this:
(assoc-in input [1 11] {:id 102 :name "Ringo"})
which yields
{1 {10 {:id 101 :name "Paul"}
11 {:id 102 :name "Ringo"}
20 {}}
2 {30 {} 40 {}}
3 {50 {} 60 {}}}
Assoc-in doesn't need to point all the way to the deepest level of a structure.
If you use two calls to assoc-in you can use the second one to change the name "Paul" to "1x2" as per your example:
(assoc-in
(assoc-in input [1 11] {:id 102 :name "Ringo"})
[1 10 :name] "1x2"))
Which returns
{1 {10 {:id 101 :name "1x2"}
11 {:id 102 :name "Ringo"}
20 {}}
2 {30 {} 40 {}}
3 {50 {} 60 {}}}
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