How would you write a function that does this: based on some parameters, it produces a map. IF one of the parameters is non-nil, THEN the map needs to contain an extra key/value pair based on that parameter. I can do something like this:
(defn myfun [a b]
(let [result {:a a
:foo (foo-fun a b)
:bar (bar-fun a b}]
(if b
(assoc result :b (extra-fun b))
result)))
or:
(defn myfun [a b]
(merge {:a a
:foo (foo-fun a b)
:bar (bar-fun a b}
(when b {:b (extra-fun b)})
or:
(defn myfun [a b]
(let [result {:a a
:foo (foo-fun a b)
:bar (bar-fun a b}
result (when b (assoc result :b (extra-fun b)))]
result))
And I could probably come up with half a dozen more ways to write it. How would you write it?!I'd go with option b personally, not sure if there are better ways of writing it
b for me
cond->
might be an option as well
(defn myfun [a b]
(cond-> {:a a
:foo (foo-fun a b)
:bar (bar-fun a b)}
b (assoc :b (extra-fun b))))
@stefan.van.den.oord The last alternative returns nil if b is false, in contrast to the first two. (Note that you're testing against truthiness, not against nil, but I assume b isn't a bool.)
I would also go with the second alternative. But, does it matter if :b
is present and nil
?
So,
(defn myfun [a b]
{:a a
:foo (foo-fun a b)
:bar (bar-fun a b)
:b (when b
(extra-fun b))})
instead. Or I guess you'd want the key to be named extra
, now that I think about it.not exactly the same problem, but I have written this in a few projects already
(defn maybe-assoc
"Assocs value v at key k to a map only if v is not `nil`"
[m k v]
(cond-> m
(some? v)
(assoc k v)))
I would probably have a maybe-update
flavor of the above for this case, accepting a function as input