Map destructuring in Clojure
Reads an order map by key, then applies the same form to a function parameter with a default.
;; {:keys [...]} pulls several keys out of a map in one binding form.
(def order {:sku "CB-14" :quantity 3 :unit-price 12.5})
(let [{:keys [sku quantity unit-price]} order]
(println (format "%s x%d = %.2f" sku quantity (* quantity unit-price))))
;; The same form works in a parameter list. :or supplies defaults for
;; keys the caller left out, and :as names the map that came in.
(defn describe-shipment
[{:keys [carrier service] :or {service "ground"} :as shipment}]
(format "%s by %s (%d fields)" carrier service (count shipment)))
(println (describe-shipment {:carrier "Pike Freight" :service "air"}))
(println (describe-shipment {:carrier "Pike Freight" :weight 40}))
How it works
(let [{:keys [sku quantity unit-price]} order]binds three keys at once, naming each local after its keyword.describe-shipmentdestructures its parameter in place, where:or {service "ground"}fills in a value the caller omitted.:as shipmentkeeps the incoming map bound, so(count shipment)can report how many keys arrived.
Keywords and builtins used here
countdefdefnformatletprintln
The run, in numbers
- Lines
- 14
- Characters to type
- 675
- Tokens
- 97
- Three-star pace
- 65 tpm
At the three-star pace of 65 tokens a minute, this run takes about 90 seconds.
Step 2 of 3 in Destructuring, step 20 of 27 in Language basics.