7

For example, let's say I have a list

'("The" " " "Brown" " " "Cow")

I want to turn this into

"The Brown Cow" 

Is there a command in clojure that does this?

5
  • 6
    Google is your friend: clojuredocs.org/clojure.string/join Commented Mar 9, 2016 at 6:15
  • Also, if you use interleave, you don't even need the actual spaces in your list. Commented Mar 9, 2016 at 10:55
  • Please convert your question from a quoted-list to a vector: [ "The" " " "Brown" " " "Cow" ] Commented Mar 9, 2016 at 21:30
  • @AlanThompson ... Why? Whether it's a list or a vector doesn't affect the question in the slightest. Commented Mar 10, 2016 at 2:38
  • I just thought it would be less confusing for new people to read. A quoted list is kind of like saying, "This is a function call form that I'm not using as a function call". Commented Mar 10, 2016 at 18:57

3 Answers 3

24

I would rather use apply for that:

(apply str '("The" " " "Brown" " " "Cow"))

Since it calls the function just once, it is much more efficient for large collections:

(defn join-reduce [strings] (reduce str strings))
(defn join-apply [strings] (apply str strings))

user> (time (do (join-reduce (repeat 50000 "hello"))
                nil))
"Elapsed time: 4708.637673 msecs"
nil
user> (time (do (join-apply (repeat 50000 "hello"))
                nil))
"Elapsed time: 2.281443 msecs"
nil
Sign up to request clarification or add additional context in comments.

1 Comment

To be more specific, it does perform better because using the variadic overload of str requires only one StringBuilder instance.
1

As Chris mentioned you can just use clojure.string/join

another way without using a library (assuming you don't want any spaces.) is:

(reduce str '("The" " " "Brown" " " "Cow"))

will return

"The Brown Cow"

str takes a list of things and turns them into one string. You can even do this: (str "this is a message with numbers " 2 " inside")

4 Comments

isn't (apply str coll) better? since it calls the str function just once, while reduce does it (dec (count coll)) times.
@leetwinski Yes. There's never a reason to call reduce str on a sequence.
Didn't know that, sorry guys! I'm pretty new to Clojure.
@JustGage Don't worry too much about it; this is just another way to learn new things. I'm guessing that the main reason your answer has been downvoted so much is that it happened to be accepted by the OP.
-1

Please, people, just say 'No' to the lists! So simple with vectors:

(ns clj.demo
  (:require [clojure.string :as str] ))

(def xx [ "The"  " "  "Brown"  " " "Cow" ] )
(prn (str/join xx))
;=> "The Brown Cow"

Quoted lists like:

'( "The"  " "  "Brown"  " " "Cow" )

are much harder to type and read, and also more error-prone than a simple vector literal:

 [ "The"  " "  "Brown"  " " "Cow" ]

Also cut/paste is much easier, as you don't need to worry about adding the quote or forgetting to add it.

Note that (str/join ... can also accept an optional separator as the first argument. You can either use the 1-char string like the first example or a "literal" as in the 2nd example:

(ns clj.demo
  (:require 
    [clojure.string :as str] 
    [tupelo.core :as t] ))

  (let [words ["The" "Brown" "Cow"]]
    (t/spyx (str/join " "    words))
    (t/spyx (str/join \space words)))

with results

(str/join " "    words) => "The Brown Cow"
(str/join \space words) => "The Brown Cow"

2 Comments

vectors? as far as i know, clojure.string/join works for any seq. What did you want to say? that using vector is faster here? No, it's not. In fact join is even a bit slower than apply str in this particular case.
He wants to say that the idiomatic default literal for sequentials in Clojure source code is the vector. This readability over performance tradeoff is made in every notable codebase. str/join is a fine solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.