Reputation: 2235
This is valid:
{:a :v (if true :f) :r }
This is not
{:a :v (if true {:f :r}) }
Since it wants to put a new hashmap in the structure
I need to return in that if
a special structure (that I have forgotten its name)
that contains the key and value so it gets inserted in the hash map.
Thanks
Upvotes: 2
Views: 2273
Reputation: 7328
Conditional threading macros are often helpful for this sort of thing. Especially if you are already using them to apply a series of transform to your data. Here's a sketch of creating http headers
(let [compressed? true
custom-header? false]
(-> {:content-type "text/plain"}
(cond-> compressed? (assoc :content-encoding "gzip"))
(cond-> custom-header? (assoc :my-custom-header "foo"))
clojure.walk/stringify-keys))
;=> {"content-encoding" "gzip", "content-type" "text/plain"}
Upvotes: 4
Reputation: 2600
The second case fails not because the if
form is returning the wrong type of value but because the map contains an odd number of items. Map literals must contain an even number of forms, and the if
is a single form.
There are several ways to add things to maps in Clojure.
You can use conj
with either a vector or a map argument:
(conj {:a :v} [:f :r]) ;;=> {:f :r, :a :v}
(conj {:a :v} {:f :r}) ;;=> {:f :r, :a :v}
You can use assoc
with the key and val as separate arguments:
(assoc {:a :v} :f :r) ;;=> {:f :r, :a :v}
Or you can use merge
with two (or more) maps as arguments:
(merge {:a :v} {:f :r}) ;;=> {:f :r, :a :v}
The special structure you're thinking of may be a MapEntry
. That's what the items are in a seq created by calling seq
on a map.
For instance:
(seq a-map) ;;=> ([:a :v] [:f :r])
(first (seq a-map)) ;;=> [:a :v]
(-> a-map seq first class) ;;=> clojure.lang.MapEntry
Map entries look and behave just like vectors, with one addition. You can use the key
and val
functions to access the key and val respectively (effectively equivalent to (get map-entry 0)
and (get map-entry 1)
).
(key map-entry) ;;=> :a
(val map-entry) ;;=> :v
You can conj
a map entry onto a map just like you can a vector.
Upvotes: 4
Reputation: 2543
Is this what you need?
(merge {:a :v} (if true {:f :r}))
=> {:f :r, :a :v}
Upvotes: 3