问题
This question will probably end in a facepalm, but I've tried for a while and am still stuck despite reading through the hyperspec.
Basically what I want to do is something like
(format t "~{|~{ ~5d~}|~%~}" '((1 23 2 312) (23 456 1 7890)))
but instead of hard-coding the 5 it should be calculated from the list (length of longest element from any nested list + 1) to give something like
| 1 23 2 312|
| 23 456 1 7890|
Maybe I'm thinking way too complicated here and there is an easier way to do what I want, but I think I ran myself into a mental corner that I can't get out of.
回答1:
Assuming the required width is bound to width
, then you can do this:
(format t "~{|~{ ~Vd~}|~%~}" width '((1 23 2 312) (23 456 1 7890)))
5
has been replaced by V
and width
has been added as an argument to FORMAT
/
edit: original answer did not correctly account for the nested directives
In a format control string V
may be used in place of any constant value, indicating that the corresponding value is to be taken from the argument list instead.
You can try this:
(setf width 5)
(setf data '((1 23 2 312) (23 456 1 7890)))
(format t "~{|~{ ~{~Vd~}~}|~%~}"
(mapcar #'(lambda (r) (mapcar #'(lambda (v) (list width v)) r)) data) )
This format string requires the desired width to precede each value. The (mapcar ...)
expression accomplishes this.
回答2:
I think that you have two options: let the format
magic go and use other looping constructs or generate the format string itself:
(defun facepalm-printer (lol)
(format t (format nil "~~{|~~{ ~~~ad~~}|~~%~~}"
(longest-member lol))
lol))
The definition of longest-member
is left as an exercise to the reader.
来源:https://stackoverflow.com/questions/4618503/format-help-with-printing-a-table