Array-map example in clojure

808 views Asked by At

I am learning clojure and trying to implement a problem. I am storing maps in a vector. Each map contains an id. For example [{:id 1 :name "abc"} {:id 2 :name "xyz"}]. The map also contains some more fields.

I read somewhere that, instead of using a vector to store the maps, I could use an array-map and do away with my id and store it something like {1 {:name "abc"}, 2 {:name "xyz"}}.

I tried going through the clojure docs but didn't find a good example to achieve this. Can some please help me out and give me a good example?

2

There are 2 answers

0
turingcomplete On BEST ANSWER

You can use assoc to add values to a map. assoc takes 3 args. The first arg is the map that you want to add to, 2nd arg is a key, and the third is a value. The function returns the old map with the key-value pair added.

Example:

(assoc {} 1 {:name "abc"})

returns

{1 {:name "abc"}}
1
Thumbnail On

Your idea is to lift the :id entry of each record-map into an index, while removing it from the map. You end up with a map of :id-less records instead of a vector of full records.

The following function lifts the key fk out of the collection of maps ms:

(defn key-by [fk ms]
  (into {} (map (fn [m] [(get m fk) (dissoc m fk)]) ms)))

For example,

(key-by :id [{:id 1 :name "abc"} {:id 2 :name "xyz"}])
;{1 {:name "abc"}, 2 {:name "xyz"}}

Note:

  • Every record should have an :id.
  • Your :ids had better be distinct, or you'll lose records.
  • Don't depend on array-map: it's an implementation detail. A modified version might well be a hash-map.
    • If you need your map sorted by key, use a sorted-map.
    • If you need to keep your records in insertion order, think again.