Сопоставление над вектором, выполняющим побочные эффекты
Я пытаюсь выполнить итерацию по вектору "строк" в Clojure. По существу, это выглядит так:
[{:start {:x 1 :y 3 :z 4}, :end {:x 3 :y 7 :z 0}}, ...]
Я хотел бы применить функцию, которая печатает каждую из этих "строк" на новой строке, ala:
(map #(println %) vector-of-lines)
но это не вызовет функцию. Должен ли я использовать функцию "map" в этом случае?
Ответы
Ответ 1
(dorun (map println vector-of-lines))
dorun
заставляет оценивать ленивую последовательность, но также отбрасывает отдельные результаты каждого из элементов в последовательности. Это идеально подходит для последовательностей, которые предназначены исключительно для побочных эффектов, которые именно вы хотите здесь.
Ответ 2
map
ленив и не будет реализовывать результаты, если вы не попросите их. Если вы хотите выполнить побочный эффект для каждого элемента в последовательности и не заботитесь о возвращаемом значении, используйте doseq
:
;; returns nil, prints each line
(doseq [line vector-of-lines]
(println line))
Если вы заботитесь о возвращаемом значении, используйте (doall)
:
;; returns a sequence of nils, prints each line
(doall (map println vector-of-lines))
Ответ 3
Чтобы добавить к ответу Джастина, doseq
- это макрос, и, таким образом, он несет в себе все ограничения макросов.
Я бы написал функцию foreach
, которая внутренне использует doseq
.
user=> (defn foreach [f xs] (doseq [x xs] (f x)))
#'user/foreach
user=> (foreach println [11 690 3 45])
11
690
3
45
nil