0

I want to create a vector of maps like this:

[{:patid 0} {:patid 1} {:patid 2}]
=> [{:patid 0} {:patid 1} {:patid 2}]

How would I create a vector of n maps? The closest I've gotten is this:

(defn patientid [n]
    (interleave (repeat n :patid) (range n)))

(patientid 3)
=> (:patid 0 :patid 1 :patid 2)

Is there a function to convert this list into maps?

0

3 Answers 3

4

This should do the trick:

(mapv (partial hash-map :patient-id) (range 3))
=> [{:patient-id 0} {:patient-id 1} {:patient-id 2}]

This is mapping (mapv to return a vector as requested) over a range of integers, and creating a map for each one. hash-map is a function that takes key/value pairs, and this uses partial to create a partial function (that's only missing the number). For example, this is slightly longer but functionally equivalent and maybe easier to understand using a map literal:

(mapv (fn [n] {:patient-id n}) (range 3))
Sign up to request clarification or add additional context in comments.

Comments

1

I like to keep it simple:

(def map-list
  (for [i (range 5)]
    {:patient-id i}))
(println map-list)

=> ({:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4})

If you want it in a vector (my favorite) instead of a lazy list, use vec:

(def map-vec (vec map-list))
(println map-vec)

=> [{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

Comments

0

The most efficient way would be this:-

(defn generate-n [n]
  (persistent! (loop [out (transient []) x 0]
                 (if (< x n)
                   (recur (conj! out {:patient-id x}) (inc x))
                   out)))
  )

Here are some tests results:-

user=> (time (mapv (fn [n] {:patient-id n}) (range 5)))
"Elapsed time: 0.476472 msecs"
[{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

user=> (time (mapv (fn [n] {:patient-id n}) (range 5)))
"Elapsed time: 0.1545 msecs"
[{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

user=> (time (mapv (fn [n] {:patient-id n}) (range 5)))
"Elapsed time: 0.143853 msecs"
[{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

user=> (time (mapv (fn [n] {:patient-id n}) (range 5)))
"Elapsed time: 0.163187 msecs"
[{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

With loop recur :-

user=> (time (generate-n 5))
"Elapsed time: 0.033539 msecs"
[{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

user=> (time (generate-n 5))
"Elapsed time: 0.032465 msecs"
[{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

user=> (time (generate-n 5))
"Elapsed time: 0.031155 msecs"
[{:patient-id 0} {:patient-id 1} {:patient-id 2} {:patient-id 3} {:patient-id 4}]

3 Comments

The loop/recur answer is correct but it is less, not more efficient than the solution with mapv, which uses reducible/transients internally. You’re measuring the wrong thing.
Yes. You are right. But now I have updated my answer. Using mapv and my code both are almost same, but in the above Taylor Wood's solution two loops are being used which is not necessary.
Do let me know if I am wrong.. I am just a beginner :-)

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.