Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does clojure have a merge-if-exists function?

Tags:

clojure

Does clojure have a merge-if-exists function to merge two maps, like

(defn merge-if-exists [map1 map2])

return a new map containing all keys of map1, and if a key occurs in more than one map, use map2's value of this key as return map value, else map1's value.

e.g.

(merge-if-exists {:a 1 :b 2} {:b 3})
;=> {:a 1, :b 3}

(merge-if-exists {:a 1 :b 2} {:c 3})
;=> {:a 1, :b 2}

(merge-if-exists{:b 3} {:a 1 :b 2})
;=> {:b 2}

How to write this function?

like image 740
Yeezh Avatar asked Apr 09 '26 17:04

Yeezh


2 Answers

You could define this with merge and select-keys:

(defn merge-if-exists [m1 m2]
  (merge m1 (select-keys m2 (keys m1))))

(merge-if-exists {:a 1 :b 2} {:b 3})
=> {:a 1, :b 3}
(merge-if-exists {:a 1 :b 2} {:c 3})
=> {:a 1, :b 2}
(merge-if-exists {:b 3} {:a 1 :b 2})
=> {:b 2}

Or a faster/more efficient version using reduce-kv:

(defn merge-if-exists [m1 m2]
  (reduce-kv
   (fn [m k v]
     (assoc m k (if-let [r (find m2 k)]
                  (val r)
                  v)))
   {}
   m1))
like image 65
Taylor Wood Avatar answered Apr 13 '26 05:04

Taylor Wood


You could do it as follows:

(defn merge-keep-left [left right]
  (select-keys (merge left right) (keys left)))

This function is from a post from Mark Needham. He also showcases alternative implementation in the blogpost.

like image 27
WeGi Avatar answered Apr 13 '26 04:04

WeGi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!