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}]