Reputation: 143
I did:
user=> (println (for [line (range 1 5)] (str "line=" line)))
and got:
(line=1 line=2 line=3 line=4)
but I wanted only line=1 line=2 line=3 line=4
as a string. How do I do this?
Upvotes: 5
Views: 964
Reputation: 33637
What about this one. doseq
is about doing side-effect on sequences and printing is a side-effect.
(doseq [line (range 1 5)
:let [msg (str "line=" line " ")]]
(print msg))
Upvotes: 3
Reputation: 1923
Instead of apply
, you could alternatively use reduce
like so:
user> (reduce #(str %1 " line=" %2) "" (range 1 5))
=> " line=1 line=2 line=3 line=4"
The reduce
function is a function that takes a function (let's call if f), a "starting value", and then a list of things that will be used as the second argument to f. It lazily calls f on the starting value and the first item in the list, then calls f on what this returns and the second item in the list, then calls f on what this returns and the third item in the list etc., until it has exhausted all the items in the list (or rather--since it's lazy, it will only go through the whole list if you "ask it to").
If you don't like starting space, you could wrap the whole thing in triml
(you'd have to do (use 'clojure.string)
first). Or you could do (reduce #(str %1 "line=" %2 " ") (range 1 5))
, which would put the space at the end.
My experience has been that anytime you can do something with apply
, you can do it slightly more elegantly with reduce
. More importantly, my reduce
alternative has always usually been faster than my apply
one. I certainly can't vouch that this will be true always, and I haven't done speed tests for your particular problem.
Edit
I did some rough timings, using my version (reduce
) versus JohnJ's second suggestion (apply
), and found that they were pretty similar for up to (range 1 100)
, but that by (range 1 500)
, the apply
version was at least 4x faster.
Upvotes: 2
Reputation: 4833
You need 'apply'.
(apply println (for [line (range 1 5)] (str "line=" line)))
Alternatively,
(println (apply str (interpose " " (map #(str "line=" %) (range 1 5)))))
Upvotes: 10