Clojure是否有一个merge-if-exists函数?

3
Clojure是否有一个merge-if-exists函数来合并两个映射,就像...
(defn merge-if-exists [map1 map2])

返回一个新的映射,其中包含map1的所有键,如果一个键出现在多个映射中,则使用map2的该键值作为返回映射的值,否则使用map1的该键值。

例如:

(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}

如何编写这个函数?
2个回答

8
你可以使用mergeselect-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}

或者使用 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))

2
您可以按照以下步骤进行操作:

最初的回答:

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

这个函数来自于Mark Needham的一篇文章。他在博客中也展示了其他的实现方式。"Original Answer"翻译成"最初的回答"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接