What is a map?
A map is an associative data structure associating keys to values. Other languages call a map a hash table, a dictionary or a lookup table. If you're familar with JavaScript, a Clojure map is similar to a JavaScript object. One way to think of a map is that they are like vectors (or arrays in other languages) except vector/array associates a integer key called the index to a value. A map is different in that the key can be any arbitary value not just an integer. Another differences with vectors are entries in a Map are unordered
Maps, like all Clojure data structures are immutable and implement Persistent data structures
What is a keyword?
Keywords are like strings except they start with : instead of being enclosed in double quotes. Unlike strings keywords can be namespaced
(def jane {:age 10 ;; :age is a keyword and 10 is the value associated with :age
:person/first-name "Jane" ;; :person/first-name is a namespaced keyword.
:person/last-name "Doe"
42 "answer to life" ;; 42 is the key "answer to life" is the value
})
(prn "age=" (:age jane))
(prn "another way of getting age" (jane :age))
(prn "first-name" (:person/first-name jane))
(prn "last-name" (jane :person/last-name))
(prn "the value associated with the 42 key is:" (jane 42))
(comment
why does (:age jane) work but (42 jane) fails?
A rule of Clojure evaluation is the first position in a list must be something
that is callable like a function.
Since :age and jane work in the first position of a list, it must mean that :age and jane
are both callable functions but 42 is not a callable function.
This is why (:age jane) and (jane :age) will both return the value 10. When the key in a map
is a keyword, it is idiomatic Clojure to use (:age jane) instead of (jane :age) . However, if
the key is not a keyword then the later form is required for example, (jane 42))
(prn "is jane a function?" (ifn? jane))
(prn "is :age a function?" (ifn? :age))
(prn "is 42 a function?" (ifn? 42))
(comment
If maps are immutable, how can I add or remove entries to a map?
You cannot add or remove entries in a map once a map is created
but you can transform the map to a new map using various functions)
(def my-home {:address/line1 "123 Street"
:address/city "Philadelphia"
:address/state "Pennsylvania"
:address/zip "19104"})
(def jane2 (assoc jane :address my-home))
;;jane2 is a new map with an added :address entry but structually share data with jane
(prn "jane2=" jane2)
(prn "jane2 keys=" (keys jane2))
(def jane3 (dissoc jane2 :age))
(def jane3 (dissoc jane3 42))
(prn "jane3=" jane3)
(prn "jane3 keys=" (keys jane3))
The keys in a map are usually keywords but can be any arbitary value like strings or integers or other any value type