I'm looking for the best way to conditionally avoid adding an element to a map when it is being initialized/defined. In this case, I want to avoid adding an element to a map if the value for the key is nil.
(defn create-record [data]
(let [res {
:username (data :username)
:first-name (get-in data [:user-info :name :first])
:last-name (get-in data [:user-info :name :last])
:gender (get-in data [:user-info :sex])
}])
)
I don't want to add gender to the map if the results of the get-in are nil (the sex field in the data does not exist). Is there a way to do this when I create the map? I could remove all keys whose value is nil after I create the map but, in some cases, I want some keys to have nil values and others to not be in the map at all if they would have nil values.
I would use a combination of merge
and when-let
for these optional parameters.
The core idea is to merge in either a single element map or nil for each of the optional parameters. Merging in nil will do nothing, so you won't see the nil in the map.
(defn create-record [data]
(let [res (merge {:username (data :username)
:first-name (get-in data [:user-info :name :first])
:last-name (get-in data [:user-info :name :last])}
(when-let [gender (get-in data [:user-info :sex])]
{:gender gender}))]
res))
Depending on how frequently you need to do this, I would recommend writing a short macro or function around the when-let to keep the code more concise.
(cond-> {:username (data :username)
:first-name (get-in data [:user-info :name :first])
:last-name (get-in data [:user-info :name :last])}
(get-in data [:user-info :sex]) (assoc :gender (get-in data [:user-info :sex])))
(defn create-record [data]
(merge {:username (data :username)
:first-name (get-in data [:user-info :name :first])
:last-name (get-in data [:user-info :name :last])}
(when
(get-in data [:user-info :sex])
{:gender (get-in data [:user-info :sex])})))
Just add when
for each element you want to check if it is not nil
and then it will return a map to be merged or nil that will not affect the return map value.
You can merge several maps together so there is no limit of maps to merge and you can return a separate map for each element that is not nil
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With