Есть ли у clojure функция слияния, если существует? - PullRequest
3 голосов
/ 11 марта 2019

Имеет ли clojure функцию merge-if-exists для объединения двух карт, как

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

возвращает новую карту, содержащую все ключи map1, и, если ключ встречается в нескольких картах, используйте значение map2 этого ключа в качестве возвращаемого значения карты, иначе значение map1.

1010 *, например *

(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 голосов
/ 11 марта 2019

Вы можете определить это с помощью merge и 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}

Или более быстрой / более эффективной версии, используя 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 голосов
/ 11 марта 2019

Вы можете сделать это следующим образом:

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

Эта функция из поста Марк Нидхэм . Он также демонстрирует альтернативную реализацию в блоге.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...