I am attempting to iterate over a vector of "lines" in Clojure. Essentially, it looks like:
[{:start {:x 1 :y 3 :z 4}, :end {:x 3 :y 7 :z 0}}, ...]
I would like to apply a function that prints each of these "lines" onto a new line, ala:
(map #(println %) vector-of-lines)
but that doesn't appear to call the function. Should I not be using the "map" function in this instance?
(dorun (map println vector-of-lines))
dorun
forces the evaluation of the lazy sequence, but also discards the individual results of each of item in the sequence. This is perfect for sequences that are purely for side-effects which is exactly what you want here.
map
is lazy and won't realize results unless you ask for them. If you want to perform a side effect for each element in a sequence, and don't care about the return value, use doseq
:
;; returns nil, prints each line
(doseq [line vector-of-lines]
(println line))
If you do care about the return value, use (doall)
:
;; returns a sequence of nils, prints each line
(doall (map println vector-of-lines))
To add to Justin's answer, doseq
is a macro, and thus carries with it all the limitations of macros.
I would write a foreach
function that internally uses 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
Since Clojure 1.7 there is run!
which does what you want. The naming of this method may be related to the workaround with dorun
and map
. Be careful with using map
for such occasions. Suppose that you make another call to map
inside your function that you passed in. That will require walking the sequence as well. Thus, you will need to use dorun
twice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With