Working with Maps and Nested Data

Libraries for deep data manipulation: Specter (navigate and transform nested structures), medley (missing core utilities like map-vals, filter-keys, index-by), and meander (pattern-matching transformations).

(def db {:users {1 {:name "Ana" :roles #{:admin} :address {:city "Pune"}}
                 2 {:name "Bo" :roles #{} :address {:city "Delhi"}}}})

(get-in db [:users 1 :address :city])              ; "Pune"
(assoc-in db [:users 3] {:name "Cy"})
(update-in db [:users 1 :roles] conj :editor)
(update-in db [:users 2 :address] assoc :zip "110001")
(-> db (get-in [:users]) vals (->> (map :name)))   ; ("Ana" "Bo")

(merge-with + {:a 1 :b 2} {:a 10})                 ; {:a 11, :b 2}
(merge-with into {:tags [:x]} {:tags [:y]})        ; {:tags [:x :y]}
(reduce-kv (fn [acc k v] (assoc acc k (:name v))) {} (:users db))   ; {1 "Ana", 2 "Bo"}
(into {} (filter (fn [[_ v]] (seq (:roles v)))) (:users db))
(set/rename-keys {:a 1} {:a :alpha})               ; {:alpha 1}
(set/index [{:dept :eng :name "a"} {:dept :ops :name "b"}] [:dept])
(group-by :dept [{:dept :eng :n 1} {:dept :ops :n 2} {:dept :eng :n 3}])

;; Data-oriented programming: model with maps, validate with specs/Malli, transform with functions
(defn apply-discount [order pct]
  (update order :items (fn [items] (mapv #(update % :price * (- 1 pct)) items))))
(apply-discount {:items [{:sku "a" :price 100.0}]} 0.1)   ; {:items [{:sku "a", :pr
…