Say I have two maps in clojure.
(def map1 {:a 1 :b 1 :c nil :d 1})
(def map2 {:a 1 :b 2 :c 3 :d nil})
listofmaps '({:a 1 :b 1 :c nil :d 1} {:a 2 :b 2 :c 2 :d nil})
If :a value matches with any map in listofmaps and map1, then if map1 :d is not null, put :d value from map1 into the matching map in listofmaps.
Like, first we compare map1 and listofmaps - now if map1 (:a 1) matches with any maps in listofmaps (:a 1), if map1 (:d not null) replace (matching map in listofmaps with map1 :d value) and if map1 (:c not null) replace (matching map in listofmaps with map1 :c value)
map1 {:a 1 :b 1 :c nil :d 1}
listofmaps '({:a 1 :b 1 :c nil :d 1} {:a 2 :b 2 :c 2 :d nil})
Then map2 (:a 1) matches with a map in listofmaps (:a 1) and :
map2 {:a 1 :b 2 :c 3 :d nil}
listofmaps '({:a 1 :b 1 :c nil :d 1} {:a 2 :b 2 :c 2 :d nil})
if map2 (:d not null) replace (matching map in listofmaps with map2 :d value) and if map2 (:c not null) replace (matching map in listofmaps with map2 :c value)
output=> '({:a 1 :b 1 :c 3 :d 1} {:a 2 :b 2 :c 2 :d nil})
CodePudding user response:
it's not clear what is meant by in list of maps and map2, here is a reasonably common pattern of adding in missing values in priority order.
(let [map1 {:a 1 :b 1 :c nil :d 1}
map2 {:a 1 :b 2 :c 3 :d nil}
list-of-maps [{:a 1 :b 1 :c nil :d 1} {:a 2 :b 2 :c 2 :d nil}]
or-fn (fn [a b] (or a b))]
(->>
list-of-maps
(map #(merge-with or-fn % map1))
(map #(merge-with or-fn % map2))))
({:a 1, :b 1, :c 3, :d 1} {:a 2, :b 2, :c 2, :d 1})
CodePudding user response:
I understood your question to be
If the value of the :a
key in the map matches the value of the :a
key in any map in listofmaps
, then, for the keys :c
and :d
, replace the values in that particular map in listofmaps
by a new value only if the new value is not null.
Assuming that, here is an answer. If I did not understand the question correctly, please clarify and show your desired output.
user> (def map1 {:a 1 :b 1 :c nil :d 1})
#'user/map1
user> (def map2 {:a 1 :b 2 :c 3 :d nil})
#'user/map2
user> (def listofmaps [{:a 1 :b 1 :c nil :d 1} {:a 2 :b 2 :c 2 :d nil}])
#'user/listofmaps
user> (defn mapper [m ms]
(mapv (fn [elem]
(if (= (:a elem) (:a m))
(merge-with #(or %1 %2) (select-keys m [:c :d]) elem)
elem))
maps))
#'user/mapper
user> (mapper map1 listofmaps)
[{:c nil, :d 1, :a 1, :b 1} {:a 2, :b 2, :c 2, :d nil}]
user> (mapper map2 listofmaps)
[{:c 3, :d 1, :a 1, :b 1} {:a 2, :b 2, :c 2, :d nil}]
user>