How to add fields to a map in Clojure?
I have a map like this:
{:a 1 :b 20}
: and I want to make sure that certain fields are not missing from the map:
(:a :b :c :d )
: Is there a function to merge the two, something like :
(merge-missing-keys {:a 1 :b 20} (:a :b :c :d ))
: which can produce :
{:a 1 :b 20 :c nil :d nil}
?
Update:
With some pointers from the answers I found that this can be done like this:
(defn merge-missing-keys [
a-set
some-keys
]
(merge-with
开发者_JAVA百科 #(or %1 %2)
a-set
(into {} (map (fn[x] {x nil}) some-keys))))
(merge-missing-keys {:a 1 :b 20} '(:a :b :c :d :e ))
You should use merge-with
:
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 val-in-result val-in-latter).
So the following will merge all maps with one actual value selected from the maps or nil
.
(merge-with #(or %1 %2)
{:a 1 :b 2}
{:a nil :b nil :c nil :d nil})
; -> {:d nil :c nil :b 2 :a 1}
This will probably be enough for you to build your implementation.
You can always just merge into your default array as follows:
(merge
{:a nil :b nil :c nil :d nil} ; defaults
{:a 1 :b 20}) ; current values
=> {:a 1, :b 20, :c nil, :d nil}
A riff on @mikera's answer, to make it work when you don't have the keys available as literals:
(let [keys [:a :b :c :d]]
(merge (zipmap keys (repeat nil))
{:a 1 :b 20}))
精彩评论