Reputation: 418
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?
Upvotes: 1
Views: 844
Reputation: 13483
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:
:id
. :id
s had better be distinct, or you'll lose records.array-map
: it's an implementation detail. A
modified version might well be a hash-map
.
sorted-map
. Upvotes: 1
Reputation: 2188
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"}}
Upvotes: 1