Skip to content

Instantly share code, notes, and snippets.

@brandonbloom
Created January 18, 2017 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonbloom/7a76d55ffeaf4ecc46832060d659dfc1 to your computer and use it in GitHub Desktop.
Save brandonbloom/7a76d55ffeaf4ecc46832060d659dfc1 to your computer and use it in GitHub Desktop.
(defn merge-keyed
"Returns a map that consists of the rest of the maps conj-ed onto
the first. If a key occurs in more than one map, the mapping(s)
from the latter (left-to-right) will be combined with the mapping in
the result by calling (f key val-in-result val-in-latter)."
[f & maps]
(when (some identity maps)
(let [merge-entry (fn [m e]
(let [k (key e) v (val e)]
(if (contains? m k)
(assoc m k (f k (get m k) v))
(assoc m k v))))
merge2 (fn [m1 m2]
(reduce merge-entry (or m1 {}) (seq m2)))]
(reduce merge2 maps))))
(defmulti -union (fn [k lv rv] k))
(defmulti -intersect (fn [k lv rv] k))
(defn union [& maps]
(apply merge-keyed -union maps))
(defn intersect [& maps]
(apply merge-keyed -intersect maps))
(defmethod -union ::min [_ x y] (min x y))
(defmethod -union ::max [_ x y] (max x y))
(defmethod -intersect ::min [_ x y] (max x y))
(defmethod -intersect ::max [_ x y] (min x y))
(def a {::min 3 ::max 5})
(def b {::min 4 ::max 7})
(comment
(union a b)
(intersect a b)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment