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