Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lisp 格式-打印表格的帮助_Lisp_Format - Fatal编程技术网

Lisp 格式-打印表格的帮助

Lisp 格式-打印表格的帮助,lisp,format,Lisp,Format,这个问题可能会以facepalm结束,但我已经尝试了一段时间,尽管阅读了hyperspec,但仍然卡住了 基本上我想做的是 (format t "~{|~{ ~5d~}|~%~}" '((1 23 2 312) (23 456 1 7890))) | 1 23 2 312| | 23 456 1 7890| 但是,与其硬编码5,还不如从列表(任何嵌套列表中最长元素的长度+1)中计算出 (format t "~{|~{ ~5d~}|~%~}

这个问题可能会以facepalm结束,但我已经尝试了一段时间,尽管阅读了hyperspec,但仍然卡住了

基本上我想做的是

(format t "~{|~{ ~5d~}|~%~}" '((1 23 2 312) (23 456 1 7890)))
|    1    23     2   312|
|   23   456     1  7890|      
但是,与其硬编码5,还不如从列表(任何嵌套列表中最长元素的长度+1)中计算出

(format t "~{|~{ ~5d~}|~%~}" '((1 23 2 312) (23 456 1 7890)))
|    1    23     2   312|
|   23   456     1  7890|      

也许我的想法太复杂了,有一种更简单的方法来做我想做的事情,但我觉得我自己陷入了一个无法摆脱的精神困境。

我认为你有两个选择:让
格式
魔术走,使用其他循环构造或生成格式字符串本身:

(defun facepalm-printer (lol)
  (format t (format nil "~~{|~~{ ~~~ad~~}|~~%~~}"
                    (longest-member lol))
          lol))
最长成员的定义
留给读者作为练习。

假设所需宽度绑定为
宽度
,则可以执行以下操作:

(format t "~{|~{ ~Vd~}|~%~}" width '((1 23 2 312) (23 456 1 7890)))
5
已替换为
V
width
已添加为
FORMAT
/

编辑:原始答案没有正确解释嵌套指令

在格式控制中,可以使用字符串
V
来代替任何常量值,表示相应的值将从参数列表中取而代之

您可以尝试以下方法:

(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) )

此格式字符串要求在每个值之前具有所需的宽度。
(mapcar…
表达式可以实现这一点。

可能有一个
~
控件来完成您想要的操作,但我只需分两步完成:计算最宽的元素,然后使用它构建一个格式字符串(带格式!),然后调用format来构建表。所以它是一个三行函数而不是一行函数。:-)+回答得好。最大宽度至少很容易计算(至少如果所有数字都是正数)。例如,
(1+(应用#'max(mapcar#'(lambda(x)(floor(logx10))))(110 100 1000 200000))
。我简洁地拒绝了这个解决方案,因为临时将宽度拼接到参数列表中对我来说似乎不必要的复杂和浪费。+1被接受,因为
V
正是我想要的(而且似乎一再漏掉了)。不过,我确实明白Svanet的观点,所以这里也有+1:)@Svante:我同意将宽度拼接到列表中可能会花费高昂。然而,调用格式化也是相当昂贵的。对于小列表,列表拼接的成本较低(在空间和时间上),而对于大列表,拼接的成本更高。交叉点必须通过使用实际数据进行基准测试来确定。双格式的方法显然可以更好地扩展——特别是在空间上。我回答这个问题的主要动机是指出“V”在格式控制字符串中的作用。