I have this map:
{:a {:a {:a 1 :b 2}}}
And I want to turn it into this one:
{:a {:a {:x 1 :b 2}}}
I tried this, but -of course- got all :a
replaced:
(clojure.walk/postwalk-replace {:a :c} {:a {:a {:a 1 :b 2}}})
-> {:c {:c {:c 1, :b 2}}}
I tried this, but got a result I can't even interpret:
(update-in {:a {:a {:a 1 :b 2}}} [:a :a] clojure.walk/postwalk-replace {:a :c})
-> {:a {:a {1 :c}}}
What can I do?
There is a clojure.set/rename-keys
. E.g.
(update-in {:a {:a {:a 1 :b 2}}} [:a :a] clojure.set/rename-keys {:a :c})
; → {:a {:a {:b 2, :c 1}}}
The reason, why your example fails is the argument order.
postwalk-replace
needs the first argument to be the replacement map
and the second argument to what is to be renamed. But update-in
always sends the traversed things as first argument into the function.
So you need to juggle the arguments around (e.g. via an anon-fn or with
partial
):
(update-in {:a {:a {:a 1 :b 2}}} [:a :a] (partial clojure.walk/postwalk-replace {:a :c}))
; → {:a {:a {:b 2, :c 1}}}