Reputation: 1558
I am trying to model this kind of data in Clojure
name: foo data: bar
name: stack data: overflow
name: tess data: ting
I thought about using a map, but you can't have duplicated keys in there so that wouldn't work.
Is it possible to have an array of maps, similar to:
[{name: foo, data: bar}
{name: stack, data: overflow}
{name: tess, data: ting}]
if it is, how would you access the data. for example, how would you access data: overflow
would you have to use a nested get
statement?
Upvotes: 1
Views: 953
Reputation: 38809
Maybe I am missing something, but it looks as-if you are reinventing a map where instead of keys and values you want to have names and data. For example, the following is sufficient to model your map:
(get {"foo" "bar" "stack" "overflow" "tess" "ting"} "stack")
=> "overflow"
Now, if your data is more complex, you can certainly store a map under an certain key. In other words, you build a map where the key is the name associated with each data. Suppose you have a vector of such things:
(def data [{:name "foo" :data "bar"}
{:name "stack" :data "overflow"}
{:name "tess" :data "ting"}])
In order to have the corresponding map, you can do:
(reduce (fn [m d] (assoc m (:name d) d)) {} data)
... which gives:
{"tess" {:name "tess" , :data "ting"},
"stack" {:name "stack", :data "overflow"},
"foo" {:name "foo" , :data "bar"}}
Upvotes: 4
Reputation: 1355
First, {:name "foo" :data "overflow"}
, this is EDN, not JSON;
Second, yes, it's ok to (def map-array [{:name "foo"} {:name "bar"}])
To get access to fields you can use get
and get-in
:
https://clojuredocs.org/clojure.core/get-in.
(get-in map-array [1 :name])
=> "bar"
You can also use filter
function in such way:
(first (filter #(= "foo" (:name %)) map-array))
=> {:name "foo"}
EDIT:
If you want to get rid of filter
to and get constant access time to your maps, you should use some kind of uniq ID:
(def map-array {:id1 {:name "foo"}
:id2 {:name "bar"}})
(get-in map-array [:id1 :name])
=> "foo"
;; using threading macro and keyword special power:
(-> map-array :id2 :name)
=> "bar"
Upvotes: 2