打印长列表拆分为X列

时间:2012-06-27 12:32:19

标签: lisp format common-lisp

有没有办法做到这一点:

(defvar long-list ((1 1 1 1) (2 2 2 2) (3 3 3 3)
        (4 4 4 4) (5 5 5 5) (6 6 6 6))
(format t "magic" long-list)

输出如下内容:

(1 1 1 1) (2 2 2 2) (3 3 3 3)
(4 4 4 4) (5 5 5 5) (6 6 6 6)

我在哪里定义要打印的列数?

我知道(format t "~/my-function/" long-list)选项,但也许有内置的东西?

该引用对此特定主题非常无益。

1 个答案:

答案 0 :(得分:3)

好的,对不起,我实际上找到了它:http://www.lispworks.com/documentation/lw51/CLHS/Body/f_ppr_fi.htm#pprint-tabular但在我找到它之前,我写了这个:

(defun pplist-as-string (stream fmt colon at)
  (declare (ignore colon at))
  (dolist (i fmt)
    (princ i stream)))

(defun ppcolumns (stream fmt colon at cols)
  (declare (ignore at colon))
  (when (or (not cols) (< cols 1)) (setq cols 1))
  (let* ((fmt-length (length fmt))
         (column-height (floor fmt-length cols))
         (remainder (mod fmt-length cols))
         (printed 0)
         columns
         column-sizes)
    (do ((c fmt (cdr c))
         (j 0 (1+ j))
         (r (if (zerop remainder) 0 1) (if (zerop remainder) 0 1))
         (i 0 (1+ i)))
        ((null c))
      (when (or (= j (+ r column-height)) (zerop i))
        (setq columns (cons c columns)
              column-sizes
              (cons
               (+ r column-height) column-sizes))
        (unless (zerop remainder)
          (unless (zerop i) (decf remainder)))
        (setq j 0)))
    (setq columns (reverse columns)
          column-sizes (reverse column-sizes))
    (when (/= fmt-length (* column-height cols))
      (incf column-height))
    (dotimes (i column-height)
      (do ((c columns (cdr c))
           (size column-sizes (cdr size)))
          ((or (null c)))
        (when (> printed (1- fmt-length))
          (return-from ppcolumns))
        (when (< 0 (car size))
          (pplist-as-string stream (caar c) nil nil)
          (when (caar c) (incf printed))
          (unless (null c) (princ #\ ))
          (rplaca c (cdar c))))
      (princ #\newline))))

以另一个方向打印它。如果您需要它。