typestar

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

  1. (let [{:keys [sku quantity unit-price]} order] binds three keys at once, naming each local after its keyword.
  2. describe-shipment destructures its parameter in place, where :or {service "ground"} fills in a value the caller omitted.
  3. :as shipment keeps the incoming map bound, so (count shipment) can report how many keys arrived.

Keywords and builtins used here

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.

Type this snippet

Step 2 of 3 in Destructuring, step 20 of 27 in Language basics.

← Previous Next →