juise
juise

Reputation: 143

How to print a list as a string without parentheses

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

Answers (3)

Ankur
Ankur

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

Omri Bernstein
Omri Bernstein

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

JohnJ
JohnJ

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

Related Questions