Definition

A map in Clojure is a key-value data structure that stores associations between keys and values.

  • Keys are unique (no duplicate keys)
  • Maps are unordered by default (unless you use a sorted map)
  • Maps are immutable (modifications return a new map instead of modifying the original)

Clojure supports two main types of maps:

  • HashMap ({}) – Unordered, optimized for fast lookup.
  • SortedMap (sorted-map) – Ordered by key, useful when ordering matters.

Syntax

A Clojure map is represented using curly braces {} with key-value pairs:

{:key1 value1, :key2 value2, :key3 value3}

Keys are often keywords (:name), but they can also be strings, symbols, or numbers.
Values can be anything, even map.

Common Use Cases

Clojure maps are used for:

  • Data Representation – Storing structured information like user profiles, configurations, etc
  • Associative Lookup – Fast key-based retrieval of values
  • Transformations – Using functions like assoc, dissoc, merge, map, reduce on maps
  • Sorting & Grouping – Organizing data using sorted-map or group-by

Practicing:

Create and Manipulate Maps
Create a map representing a student with keys :name, :age, and :grade. Add a new key :hobby with a value, and update the :grade to a new value.

(def student {:name "Johnny" :age "30" :grade "A"})
(def studentWithHobby (assoc student :hobby "Clojure"))
(def studentGotB (assoc studentWithHobby :grade "B"))

Access Map Values
Given a map of product prices (e.g., {:apple 1.2 :banana 0.5 :cherry 2.5}), retrieve the price of :banana and handle the case where a key does not exist (e.g., :orange).

(def productPrice {:apple 1.2 :banana 0.5 :cherry 2.5})
(productPrice :banana)
(productPrice :orange 0)

Filter Map Entries
Write a function that takes a map of people’s names and ages (e.g., {:Alice 30 :Bob 25 :Charlie 35}) and returns a new map with only people aged 30 or older.

(def people {:Alice 30 :Bob 25 :Charlie 35})
(defn filter30Above [people]
    (filter (fn [map-item] (> (val map-item) 30)), people)
  )

Merge Maps
Merge two maps: one containing a user's personal details and another containing their contact information. Handle any key conflicts by prioritizing the second map.

(def user {:id 123456 :fNmae "Ivan" :lName "Gavlik" :age 30 })
(def contact {:id 123456 :email "ivangavlik963@gmail.com" :tel "+385912266016"})
(def user-contact (merge user contact))

Map Keys and Values Transformation
Given a map of temperatures in Celsius for different cities (e.g., {:Berlin 20 :Paris 25 :Rome 30}), transform the values to Fahrenheit.

def city-temp-celsius {:Berlin 20 :Paris 25 :Rome 30})
(defn cel-to-feh
  [[key val-cel]] [key (+ (* val-cel 9/5) 32)]
  )
(def city-temp-fahrenheit
  (into {} (map cel-to-feh city-temp-celsius))
  )

Group by Key Values
Create a function that groups a sequence of maps (e.g., {:name "Alice" :department "IT"}) by the :department key.

(def employers [ {:name "Alice" :department "IT" }
                { :name "Marko" :department "HR" }
                {:name "Pero" :department "HR"}
                ])

(def bySector (group-by :department employers))


Remove Entries by Condition
Remove all entries from a map of products and their stock quantities (e.g., {:apples 5 :oranges 0 :pears 10}) where the stock is 0.

(def fruit-stock-quantities {:apples 5 :orange 0 :pears 10})
(defn exist-fruit-stock? [[fruit stock]]
  (> stock 0)
  )
(defn fruit-stock-good [fruit-stock]
  (filter exist-fruit-stock? fruit-stock-quantities)
  )
(def fruit-stock-report (into {} (fruit-stock-good fruit-stock-quantities)))

Nested Maps
Work with a nested map representing a school (e.g., {:class1 {:students ["Alice" "Bob"] :teacher "Ms. Smith"} :class2 {:students ["Charlie" "Dana"] :teacher "Mr. Johnson"}}). Add a new student to :class2.

(def school-class {
            :class1 {:students ["Alice" "Bob"] :teacher "Ms. Smith" }
            :class2 {:students ["Charlie" "Dana"] :teacher "Mr. Johnson"}
            }
  )

(defn new-student-class2 [student school-class]
  (let [class2-students (get-in school-class [:class2 :students])
        add-new-student (conj class2-students student)
        class-new-student (assoc-in school-class [:class2 :students] add-new-student)
        ]
    class-new-student
    )
  )

Count Map Entries
Write a function to count how many keys in a map have values greater than a given number. For example, in {:a 5 :b 10 :c 15}, count how many values are greater than 8.

(def letter-occurrence {:a 5 :b 10 :c 15})
(defn letter-occurrence-gt [n letter-occurrence]
  (let [filter-map (filter #(> (second %) n) letter-occurrence)
         ]
     (count filter-map)
    )
  ;;  (count (into [] (keys (filter #(> (second %) n)  letter-occurrence))))
  )

Sort Maps by Values
Sort a map of items and their prices (e.g., {:item1 20 :item2 10 :item3 30}) in ascending order of prices.

(def item-price-data {:item1 20 :item2 10 :item3 30 :item4 10})
(defn sorted-item-price [item-price] (into (sorted-map-by (fn [k1 k2]
                                          (compare [(get item-price k1) k1] [(get item-price k2) k2]))) item-price))

Task: Managing a Library System Using Maps

Scenario:

You are developing a simple library system to manage books and their availability. The system stores book records as maps, where each book has attributes like :id, :title, :author, :year, and :available?.

Your goal is to implement functions that:

  • Initialize the Library – Create a collection of book records using maps
  • Check Out a Book – Update a book’s availability status when a user borrows it
  • Return a Book – Update the book’s availability when a user returns it
  • Find Books by Author – Retrieve all books written by a specific author
  • List Available Books – Return a list of books that are currently available
  • Add a New Book – Insert a new book record into the collection.
  • Remove a Book – Delete a book from the collection based on its :id

Solution

(def library
  [{:id 1 :title "Clojure for the Brave" :author "Daniel Higginbotham" :year 2015 :available? true}
   {:id 2 :title "The Joy of Clojure" :author "Michael Fogus" :year 2014 :available? true}
   {:id 3 :title "Programming Clojure" :author "Stuart Halloway" :year 2018 :available? false}])


(defn check-out-book [library book-id]
  (map #(if (= (:id %) book-id)
          (assoc % :available? false)
          %)
       library))

(defn return-book [library book-id]
  (map #(if (= (:id %) book-id)
          (assoc % :available? true)
          %)
       library))

(defn find-books-by-author [library author]
  (filter #(= (:author %) author) library))

(defn list-available-books [library]
  (filter :available? library))

(defn add-book [library new-book]
  (conj library new-book))

(defn remove-book [library book-id]
  (filter #(not= (:id %) book-id) library))


;; Example Usage
(def updated-library (check-out-book library 2))
(def returned-library (return-book updated-library 3))
(def books-by-author (find-books-by-author library "Michael Fogus"))
(def available-books (list-available-books library))
(def expanded-library (add-book library {:id 4 :title "New Book" :author "Some Author" :year 2023 :available? true}))
(def reduced-library (remove-book library 1))


Author Of article : ivan.gavlik Read full article