Explore the power of Clojure maps, including hash maps and sorted maps, and learn how to effectively use them for key-value associations with immutable updates.
Maps are a fundamental data structure in Clojure, providing a way to associate keys with values. They are similar to Java’s HashMap
and TreeMap
, but with a focus on immutability and functional programming principles. In this section, we’ll explore Clojure’s hash maps and sorted maps, their uses, and how to perform common operations such as creating maps, accessing and updating values, and leveraging keywords as map keys.
Clojure maps are collections of key-value pairs, where each key is unique. They are immutable, meaning that any operation that modifies a map returns a new map with the changes, leaving the original map unchanged. This immutability is a core feature of Clojure’s functional programming paradigm, promoting safer and more predictable code.
Hash maps in Clojure are the most common type of map, providing efficient key-value lookups. They are similar to Java’s HashMap
, but with the added benefit of immutability.
;; Creating a hash map
(def my-map {:name "Alice" :age 30 :city "New York"})
;; Accessing values
(get my-map :name) ;=> "Alice"
;; Using keywords as functions
(:age my-map) ;=> 30
;; Checking for keys
(contains? my-map :city) ;=> true
;; Updating maps
(def updated-map (assoc my-map :age 31))
Sorted maps maintain their keys in a sorted order, similar to Java’s TreeMap
. They are useful when you need to iterate over keys in a specific order.
;; Creating a sorted map
(def sorted-map (sorted-map :b 2 :a 1 :c 3))
;; Accessing values
(get sorted-map :a) ;=> 1
;; Iterating over keys
(keys sorted-map) ;=> (:a :b :c)
Creating maps in Clojure is straightforward. You can use the literal syntax with curly braces or the hash-map
function.
;; Using literal syntax
(def my-map {:name "Bob" :age 25})
;; Using hash-map function
(def another-map (hash-map :country "USA" :language "English"))
Accessing values in a map can be done using the get
function or by treating keywords as functions.
;; Using get function
(get my-map :name) ;=> "Bob"
;; Using keywords as functions
(:age my-map) ;=> 25
Since Clojure maps are immutable, updating a map involves creating a new map with the desired changes. The assoc
, dissoc
, and merge
functions are commonly used for this purpose.
The assoc
function adds or updates key-value pairs in a map.
;; Adding a new key-value pair
(def new-map (assoc my-map :email "bob@example.com"))
;; Updating an existing key-value pair
(def updated-map (assoc my-map :age 26))
The dissoc
function removes key-value pairs from a map.
;; Removing a key-value pair
(def smaller-map (dissoc my-map :age))
The merge
function combines multiple maps into one, with later maps overriding earlier ones for duplicate keys.
;; Merging maps
(def merged-map (merge my-map {:city "Los Angeles" :age 27}))
In Clojure, keywords are often used as map keys due to their efficiency and readability. Keywords can be used as functions to retrieve values from maps, providing a concise and expressive syntax.
;; Using keywords as map keys
(def person {:first-name "Charlie" :last-name "Brown"})
;; Accessing values with keywords
(:first-name person) ;=> "Charlie"
Clojure’s maps are part of its persistent data structures, which provide efficient immutable updates. When you update a map, Clojure creates a new map that shares structure with the original, minimizing memory usage and improving performance.
graph TD; A[Original Map] -->|assoc| B[Updated Map] A -->|dissoc| C[Reduced Map] A -->|merge| D[Merged Map]
Diagram: The flow of data through Clojure’s persistent data structures, illustrating how updates create new maps while sharing structure with the original.
While both Clojure and Java provide map data structures, there are key differences:
HashMap
and TreeMap
are mutable.Experiment with the following code snippets to deepen your understanding of Clojure maps:
get
and keywords.assoc
.dissoc
and observe the changes.:title
, :author
, and :year
. Access the values using both get
and keywords.:publisher
to the book map and update the :year
key.:genre
and :pages
. Merge it with the original book map.:year
key from the merged map and verify the result.HashMap
and TreeMap
.assoc
, dissoc
, and merge
.By mastering Clojure maps, you can effectively manage key-value associations in your applications, leveraging the power of immutability and functional programming.
For further reading, explore the Official Clojure Documentation and ClojureDocs.