[ACCEPTED]-How can I convert a LazySeq of Characters to a String in Clojure?-coercion

Accepted answer
Score: 129

This works:

(apply str my-char-seq)

Basically, str calls toString() on 3 each of its args and then concatenates them. Here 2 we are using apply to pass the characters in 1 the sequence as args to str.

Score: 14

Another way is to use clojure.string/join, as follows:

(require '[clojure.string :as str] )
(assert (= (vec "abcd")                [\a \b \c \d] ))
(assert (= (str/join  (vec "abcd"))    "abcd" ))
(assert (= (apply str (vec "abcd"))    "abcd" ))

There 3 is an alternate form of clojure.string/join which accepts a 2 separator. See:

http://clojuredocs.org/clojure_core/clojure.string/join

For more complicated problems, you 1 may also wish to lookat strcat from the Tupelo library:

(require '[tupelo.core :as t] )
(prn (t/strcat "I " [ \h \a nil \v [\e \space (byte-array [97])
                  [ nil 32 "complicated" (Math/pow 2 5) '( "str" nil "ing") ]]] ))
;=> "I have a complicated string"
Score: 10

As a special case, if the underlying type 7 of the sequence in question is clojure.lang.StringSeq you can 6 also do:

(.s (my-seq))

which is extremely performant as 5 it is just pulling out the public final 4 CharSequence field from the clojure StringSeq 3 class.

Example:

(type (seq "foo"))
=> clojure.lang.StringSeq

(.s (seq "foo"))
=> "foo"

(type (.s (seq "foo")))
=> java.lang.String

an example of the timing 2 implications (and note the difference when 1 using a type hint):

(time 
  (let [q (seq "xxxxxxxxxxxxxxxxxxxx")]
    (dotimes [_ 1000000]
      (apply str q))))
"Elapsed time: 620.943971 msecs"
=> nil

(time 
  (let [q (seq "xxxxxxxxxxxxxxxxxxxx")]
    (dotimes [_ 1000000]
      (.s q))))
"Elapsed time: 1232.119319 msecs"
=> nil

(time 
  (let [^StringSeq q (seq "xxxxxxxxxxxxxxxxxxxx")]
    (dotimes [_ 1000000]
      (.s q))))
"Elapsed time: 3.339613 msecs"
=> nil

More Related questions