Sometimes when destructuring maps, you would like to bind the destructured values to their respective key name. Depending on the granularity of the data structure, using the standard destructuring scheme may be a little bit verbose.
Let's say, we have a map based record like so :
(def john {:lastname "McCarthy" :firstname "John" :country "USA"})
we would normally destructure it like so :
(let [{lastname :lastname firstname :firstname country :country} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"
here, the data structure is quite simple with only 3 slots (firstname, lastname, country) but imagine how cumbersome it would be if we had to repeat all the key names twice for more granular data structure (having way more slots than just 3).
Instead, a better way of handling this is by using :keys
(since our keys are keywords here) and selecting the key name we would like to bind to like so :
(let [{:keys [firstname lastname country]} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"
The same intuitive logic applies for other key types like symbols (using :syms
) and plain old strings (using :strs
)
;; using strings as keys
(def john {"lastname" "McCarthy" "firstname" "John" "country" "USA"})
;;#'user/john
;; destructuring string-keyed map
(let [{:strs [lastname firstname country]} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"
;; using symbols as keys
(def john {'lastname "McCarthy" 'firstname "John" 'country "USA"})
;; destructuring symbol-keyed map
(let [{:syms [lastname firstname country]} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"