在公共Lisp中是否有迭代向量的format指令?

在公共Lisp中是否有迭代向量的format指令?,format,common-lisp,Format,Common Lisp,Common Lisp支持过多的格式化指令。然而,我找不到一个方便的指令来解决我的问题。基本上,我想打印一个数字网格 使用列表可以很好地执行以下操作: (format t "~{~A|~A|~A~%~^-----~%~}" '(1 2 3 4 5 6 7 8 9)) 1|2|3 ----- 4|5|6 ----- 7|8|9 NIL 我找不到类似的构造来迭代向量~{…~}需要一个列表作为参数。无论如何,我尝试使用向量,但我的Clisp正确地指出了错误的参数类型。作为一种解决方法,我使用万能的

Common Lisp支持过多的格式化指令。然而,我找不到一个方便的指令来解决我的问题。基本上,我想打印一个数字网格

使用列表可以很好地执行以下操作:

(format t "~{~A|~A|~A~%~^-----~%~}" '(1 2 3 4 5 6 7 8 9))

1|2|3
-----
4|5|6
-----
7|8|9
NIL
我找不到类似的构造来迭代向量<代码>~{…~}需要一个列表作为参数。无论如何,我尝试使用向量,但我的Clisp正确地指出了错误的参数类型。作为一种解决方法,我使用万能的
循环
将my vector转换为一个丢弃列表

(let ((lst (loop for e across '#(1 2 3 4 5 6 7 8 9) collecting e)))
   (format t "~{~A|~A|~A~%~^-----~%~}" lst))

1|2|3
-----
4|5|6
-----
7|8|9
NIL
这是可行的,但我觉得这是一个笨拙的权宜之计。我不想只为
格式创建大量临时列表。有没有直接迭代向量的方法

出于好奇,
format
为什么不支持序列

  • 我将使用
    强制
    而不是
    循环
    向量
    s转换为
    列表
    s
  • 我不会在
    向量上使用
    格式
    +
    强制
    ;我会直接迭代
    向量。这将产生更可读(和更高效)的代码
  • format
    不支持
    vector
    s的原因可能是历史原因
  • 您可以添加更多参数(它们将由逗号分隔),或者您也可以以某种方式处理冒号和符号

    根据Svante的建议,这里是该函数的一个稍作修改的版本,它还以以下方式使用冒号和符号:冒号使其在
    prin1
    princ
    之间进行修改,而at-sign使其递归打印嵌套数组(还可以打印多维数组等,这可能更复杂……但由于时间有限,它是:

    (defun pprint-array (stream array
                         &optional colon amp
                           (delimiter #\Space) (line #\Newline))
      (if amp (loop
                 :with first-time = t
                 :for a :across array
                 :unless first-time
                 :do (when line (write-char line stream)) :end
                 :if (or (typep a 'array) (typep a 'vector))
                 :do (pprint-array stream a colon amp delimiter line)
                 :else
                 :do (if colon (prin1 a stream) (princ a stream)) :end
                 :do (setf first-time nil))
          (loop
             :with first-time = t
             :for x :across array
             :unless first-time
             :do (when delimiter (write-char delimiter stream)) :end
             :do (if colon (prin1 x stream) (princ x stream))
             (setf first-time nil))))
    

    您可能正在寻找以下内容:

    (format t "~{~A|~A|~A~%~^-----~%~}" (coerce #(1 2 3 4 5 6 7 8 9)
                                                'list))
    1|2|3
    -----
    4|5|6
    -----
    7|8|9
    NIL
    

    但我会听sds的回答,因为这肯定不是最有效和可读的方法,直接在向量上迭代。

    你可以用
    (格式t“~/func name/”某物)添加你自己的内容。
    我相信(没有硬数据,只是一些经验)使用带有适当参数的
    write
    ,而不是对由一条指令组成的格式字符串使用
    format
    调用,性能会显著提高。这在这里可能很重要,因为它在字符串的每个字符上都是紧密循环的。
    (format t "~{~A|~A|~A~%~^-----~%~}" (coerce #(1 2 3 4 5 6 7 8 9)
                                                'list))
    1|2|3
    -----
    4|5|6
    -----
    7|8|9
    NIL