How can I add an element to an array-map in Clojure? I tried using assoc but it doesn\'t get added? I essentially want to set a default value of 0 for any missing items in the e
To supplement Carcigenicate's answer, another suggestion:
I'd use merge
or assoc
on a map of defaults:
(merge {:default-1 123 :default-2 234} {:default-1 "foo"})
=> {:default-1 "foo", :default-2 234}
Note that the order of arguments to merge
matters i.e. right-most maps take precedence over left-most maps. Your default map values will only "survive" if they're not overridden by additional map(s).
(def defaults {"foo" 0, "bar" 0})
(defn create-entry [doc]
(assoc defaults "id" (str (java.util.UUID/randomUUID))))
(defn create-entry [doc]
(merge defaults {"id" (str (java.util.UUID/randomUUID))}))
Using assoc
in this example has the same effect, and I'd prefer that version.
You need to starting thinking more functional. Note how all the structures you're using are immutable; they themselves can never change. Your second last line makes a copy of entry
, but you never do anything with it; it's just thrown out. There are a few ways of dealing with situations like this where you need to transform a structure over a couple steps:
Just use let
:
(let [entry (assoc doc "id" (str (java.util.UUID/randomUUID)))
def-foo (if (empty? (get entry "foo")) (assoc entry "foo" 0) entry)]
(if (empty? (get def-foo "bar")) (assoc def-foo "bar" 0) def-foo)))
Note how the last line uses the def-foo
copy, instead of the original entry
.
Use a threading macro:
; Create a new binding, e, that will hold the result of the previous form
(as-> (assoc doc "id" (str (java.util.UUID/randomUUID))) e
(if (empty? (get e "foo")) (assoc e "foo" 0) e)
(if (empty? (get e "bar")) (assoc e "bar" 0) e))
e
is replaced by whatever the previous form evaluated to.
Note though, that if you ever find yourself using get
and assoc
on the same object, you might want to consider using update
instead, which greatly simplifies everything, especially when paired with the ->
threading macro:
(-> (assoc doc "id" (str (java.util.UUID/randomUUID)))
(update "foo" #(if (empty? %) 0 %))
(update "bar" #(if (empty? %) 0 %)))
I had to make some assumptions about what your intent was, because your code has an error that I didn't notice until after I had already submitted my answer. In your original code, your if
s don't evaluate to anything when the condition is false. I'm assuming you just don't want to change anything when they're false.