Clojure collection quirks - Maps


Map data structures in Clojure are much like associative arrays in other languages. They, however contain many never seen possibilities.


You can create maps with two syntaxes. Either by calling the hash-map function or by writing the {} map literal.

(def m1 {:one :a, :two :b, :three :c, :four :d})

One interesting fact when working with maps is that all maps with 8 or less entries maps will be created as a PersistentArrayMap an all larger maps will be a PersistentHashMap. The two differ only by inte internal representation: it seems like that small maps are better stored in an array.


Calling seq on a map returns a sequence of its key-value pairs, called entries. They are instances of clojure.lang.MapEntry but they also act like vectors.

(seq m1) 
  => ([:one :a] [:two :b] [:three :c] [:four :d])
(type (first m1)) 
  => clojure.lang.MapEntry
(vector? (first m1)) 
  => true


You can acces a value for a given key in a map with the get function.

(get {:a 1 :b 2} :a)
  => 1
(get {:a 1 :b 2} :c)
  => nil
(get {:a 1 :b 2} :c :default-value)
  => :default-value

Maps also act like functions (they implement the IFn interface). For example:

(map {true :even false :odd} 
     (map even? 
          (range 100)))
 => (:even :odd :even :odd ...)

Please note that calling a map on a missing key returns nil or the default value given as an optional third argument.


Use the assoc function to associate a new value with a given key.