Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure deep-merge to ignore nil values

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?

like image 794
Asher Avatar asked Feb 12 '23 11:02

Asher


1 Answers

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!

like image 155
Asher Avatar answered Feb 14 '23 10:02

Asher