How to write a dissoc-in command for clojure?
How about:
(defn dissoc-in
"Dissociates an entry from a nested associative structure returning a new
nested structure. keys is a sequence of keys. Any empty maps that result
will not be present in the new structure."
[m [k & ks :as keys]]
(if ks
(if-let [nextmap (get m k)]
(let [newmap (dissoc-in nextmap ks)]
(if (seq newmap)
(assoc m k newmap)
(dissoc m k)))
m)
(dissoc m k)))
Example:
(dissoc-in {:a {:b 0 :c 1}} [:a :b])
Result:
{:a {:c 1}}
dissoc-in
was once part of clojure.contrib.core
, and is now part of core.incubator
.
If you want to keep empty maps, you can alter the code slightly:
(defn dissoc-in
[m [k & ks :as keys]]
(if ks
(if-let [nextmap (get m k)]
(let [newmap (dissoc-in nextmap ks)]
(assoc m k newmap))
m)
(dissoc m k)))
Example:
(dissoc-in {:a {:b {:c 0}}} [:a :b])
Result:
{:a {}}
I write this using update-in:
(update-in {:a {:b 0 :c 1}} [:a] dissoc :b)
=>
{:a {:c 1}}