If you want to implement it directly, I would suggest something like the following:
(defn dissoc-descendents [coll descendents]
(let [descendents (if (set? descendents) descendents (set descendents))]
(if (associative? coll)
(reduce
(fn [m [k v]] (if (descendents k)
(dissoc m k)
(let [new-val (dissoc-descendents v descendents)]
(if (identical? new-val v) m (assoc m k new-val)))))
coll
coll)
coll)))
Key points to consider when implementing:
- It makes sense to convert the descendants into a set: this will allow you to quickly check membership if the set of deleted keys is large
- There is some logic to ensure that if the value does not change, you do not need to change this part of the map. This is a pretty big performance gain if large areas of the map have not changed.
source
share