Repeat string/character with (format)
Asked Answered
D

1

7

Is there a repeat directive for (format) in Common lisp, something like(I know this won't work):

(format t "~5C" #\*)

Just wondering if there isn't a more elegant way to do it than this:(from rosettacode )

(defun repeat-string (n string)
  (with-output-to-string (stream)
    (loop repeat n do (write-string string stream))))

(princ (repeat-string 5 "hi"))
Defelice answered 15/7, 2014 at 9:28 Comment(3)
possible duplicate of Lisp format a character a number of timesFelipafelipe
I just voted to close as a duplicate based on your first example which was just trying to repeat a character. You second example, though, repeats a whole string, and not all the answers in the possible duplicate address that situation. I think I'm going to retract my close vote.Osseous
@JoshuaTaylor: that's why I wrote an answer. I think you are right.Cesium
C
18
(defun write-repeated-string (n string stream)
  (loop repeat n do (write-string string stream)))

(write-repeated-string 5 "hi" *standard-output*))

Generally you can use the format iteration:

(format t "~v@{~A~:*~}" 5 "hi")

~A can output all kinds of items, not just characters. For more information see uselpa's linked answers.

Above takes the iteration number from the first argument. Thus the v behind the tilde.

The rest of the arguments will be consumed by the iteration. Thus the @.

Inside the iteration we go back one element. Thus ~:*.

It's similar to (format t "~v{~A~:*~}" 5 '("hi")), which might be simpler to understand.

Cesium answered 15/7, 2014 at 12:56 Comment(3)
(For anyone who might find the first a little cryptic, like I did): ~@{ takes the rest of the iteration's args as lists.Defelice
I found it interesting that in SBCL the loop version compiles to 25 lines of Assembly, while the format version compiles to 189 lines.Unrivalled
gigamonkeys.com/book/a-few-format-recipes.htmlPradeep

© 2022 - 2024 — McMap. All rights reserved.