1

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?

2 Answers 2

4

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"}}
Sign up to request clarification or add additional context in comments.

Comments

2

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"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.