In Ruby, "str" * 3
will give you "strstrstr". In Clojure, the closest I can think of is (map (fn [n] "str") (range 3))
Is there a more idiomatic way of doing it?

- 72,696
- 27
- 242
- 420

- 41,224
- 16
- 95
- 126
7 Answers
How about this?
(apply str (repeat 3 "str"))
Or just
(repeat 3 "str")
if you want a sequence instead of a string.

- 17,633
- 3
- 44
- 53
-
perfect! I knew there had to be something like repeat, just couldnt find it – Matt Briggs Mar 25 '11 at 22:59
-
Does `apply` hit a limit on the argument count if you have lots of repetitions? – Lassi Nov 03 '18 at 00:06
And one more fun alternative using protocols:
(defprotocol Multiply (* [this n]))
Next the String class is extended:
(extend String Multiply {:* (fn [this n] (apply str (repeat n this)))})
So you can now 'conveniently' use:
(* "foo" 3)

- 9,789
- 2
- 36
- 53
-
3+1 for code that's an order of magnitude more perverted than clojure.contrib.string/repeat :) – Joost Diepenmaat Mar 25 '11 at 23:23
-
3
Just to throw some more awesome and hopefully thought-provoking solutions.
user=> (clojure.string/join (repeat 3 "str"))
"strstrstr"
user=> (format "%1$s%1$s%1$s" "str")
"strstrstr"
user=> (reduce str (take 3 (cycle ["str"])))
"strstrstr"
user=> (reduce str (repeat 3 "str"))
"strstrstr"
user=> (reduce #(.concat %1 %2) (repeat 3 "str"))
"strstrstr"

- 72,696
- 27
- 242
- 420
-
I would also add then: `(clojure.string/join (repeatedly 3 (partial str "str")))`. Similar but different to the first one. – Andrea Richiardi Nov 30 '15 at 04:47
You could also use the repeat function from clojure.contrib.string. If you add this to your namespace using require such as
(ns myns.core (:require [clojure.contrib.string :as str]))
then
(str/repeat 3 "hello")
will give you
"hellohellohello"

- 1,866
- 1
- 12
- 8
Or use the repeat function that comes with clojure-contrib' string package. In that case you can use (clojure.contrib.string/repeat 3 "str") which results in "strstrstr".

- 9,789
- 2
- 36
- 53
-
This seems really useful, but it seems that it no longer exists. Do you know of a way to do this with Clojure 1.4? – Eric Wilson Nov 20 '12 at 02:07
-
@EricWilson [clojure.contrib was mostly migrated](http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go) to other places at the beginning of language version 1.3. clojure.contrib.string was migrated to [clojure.string](http://clojure.github.io/clojure/clojure.string-api.html) which does not appear to contain 'repeat' any longer. – Patrick May 05 '14 at 19:20
I wouldn't claim this is idiomatic, but it is also possible to repeat a string using the clojure cl-format function which clojure inherited from common lisp. Common lisp in turn transplanted it from FORTRAN which came up with this piece of work in the 50s.
And here we are in 2018...
Example:
user=> (cl-format nil "~v@{~a~:*~}" 5 "Bob")
"BobBobBobBobBob"
The format string works as follows:
- the first format specifier is
~5@{
where the five is pulled from the argument list since there is av
in front of the@
. the~5@{
in turn means iterate 5 times using the entire argument list (the string "Bob") as the iterable. - inside the curlies (the curly expression is ended by the
~}
), we print the string "Bob" with~a
and then "move the argument pointer" back one position using the~:*
construct so that we can "consume" the argument "Bob" again.
Voila, 5 repetitions of Bob.
It should be noted that cl-format
can either return the produced string (if the second argument is nil), print it to the current *out*
(if the second argument is true
), or print it to a writer (if the second argument is a writer).
For the all too gory details on the format string syntax you can refer to:
Formatted Output to Character Streams
in the common lisp the language reference and possibly to:
for why it could be argued that cl-format
is a bad idea.

- 4,124
- 1
- 13
- 21