Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

newline after every third word in a list with cl:format

How can I to add a carriage return (using ~%) after every third argument in a list?
E.g., I have now:

(format nil "~{~a ~}" (list '"one" '"two" '"three" '"four" '"five" '"six" '"seven" '"eight" '"nine" '"ten"))  
;=> "one two three four five six seven eight nine ten " 

But I would like:

;=> "one two three  
; four five six  
; seven eight nine  
; ten "  
like image 331
Martin Mohan Avatar asked Oct 22 '13 15:10

Martin Mohan


People also ask

How do I add a new line after every line in Python?

In Python, the new line character “\n” is used to create a new line.

What is newline char?

LF (character : \n, Unicode : U+000A, ASCII : 10, hex : 0x0a): This is simply the '\n' character which we all know from our early programming days. This character is commonly known as the 'Line Feed' or 'Newline Character'.

What is the line Feed character?

Line Feed Character The Line Feed (LF) character moves the cursor down to the next line without returning to the beginning of the line. This character is used as the new line character in Unix based systems (Linux, macOS X, Android, etc).

What is\ n line break?

With early computers, an ASCII code was created to represent a new line because all text was on one line. In programming languages, such as C, Java, and Perl, the newline character is represented as a '\n' which is an escape sequence. Below are examples of how the newline could be used in Perl.


1 Answers

The format string str within ~{str~} can use up more than one argument from the list on each iteration. This means that if you had a list of arguments guaranteed to be divisible by three, you could use a format string like ~{~a ~a ~a~%~}. Here's an example:

CL-USER> (format nil "~{~a ~a ~a~%~}" '(1 2 3 4 5 6))
"1 2 3
4 5 6
"

You might have a number of arguments that's not divisible by three, though, in which case you'd need to terminate an iteration early. You can use the format directive ~^ to break if there are no more arguments. Since you might end up in this situation after the first or second argument, you should add one of these after those places. Here are examples for cases with zero, one, and two trailing arguments:

CL-USER> (format nil "~{~a~^ ~a~^ ~a~%~}" '(1 2 3 4))
"1 2 3
4"
CL-USER> (format nil "~{~a~^ ~a~^ ~a~%~}" '(1 2 3 4 5))
"1 2 3
4 5"
CL-USER> (format nil "~{~a~^ ~a~^ ~a~%~}" '(1 2 3 4 5 6))
"1 2 3
4 5 6
"

You might not want that final newline when there the number of elements is divisible by three, in which case you can add a ~^ before the newline, too:

CL-USER> (format nil "~{~a~^ ~a~^ ~a~^~%~}" '(1 2 3 4 5 6))
"1 2 3
4 5 6"

This kind of construct is particularly nice for writing delimited lists:

CL-USER> (format nil "write(~{~a~^,~})" '("fd" "buf" "count"))
"write(fd,buf,count)"

These format directives (and their variants) are described in more detail in the HyperSpec (there's more in the linked page than what's quoted here):

22.3.7.4 Tilde Left-Brace: Iteration

~{str~}

This is an iteration construct. The argument should be a list, which is used as a set of arguments as if for a recursive call to format. The string str is used repeatedly as the control string. Each iteration can absorb as many elements of the list as it likes as arguments; if str uses up two arguments by itself, then two elements of the list will get used up each time around the loop. If before any iteration step the list is empty, then the iteration is terminated. Also, if a prefix parameter n is given, then there will be at most n repetitions of processing of str. Finally, the ~^ directive can be used to terminate the iteration prematurely.

You might also be interested in these questions:

  • What's the canonical way to join strings in a list?
  • Need advice on how to print a matrix in lisp
  • Formatting a list
like image 65
Joshua Taylor Avatar answered Oct 12 '22 22:10

Joshua Taylor