I'm trying to deep-merge multiple maps in Clojure. I found many solutions online, most of which look something like:
(defn deep-merge
[& xs]
(if (every? map? xs)
(apply merge-with deep-merge xs)
(last xs)))
The problem with this solution is that if one of the maps is nil, it will delete all the previous maps (so if the last map is nil, the whole function will return nil). This is not the case in the regular merge function, which ignores nil values. Is there any other easy implementation of deep-merge that ignores nil values?
I found this at: https://github.com/circleci/frontend/blob/04701bd314731b6e2a75c40085d13471b696c939/src-cljs/frontend/utils.cljs. It does exactly what it should.
(defn deep-merge* [& maps]
(let [f (fn [old new]
(if (and (map? old) (map? new))
(merge-with deep-merge* old new)
new))]
(if (every? map? maps)
(apply merge-with f maps)
(last maps))))
(defn deep-merge [& maps]
(let [maps (filter identity maps)]
(assert (every? map? maps))
(apply merge-with deep-merge* maps)))
Thank you CircleCi people!
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