我该如何格式化一个共同的lisp alist?
我开始给我写一些Common Lisp,并且只是将一些东西放在一起并对它们进行格式化。我该如何格式化一个共同的lisp alist?
让我们假设我有一个ALIST,像这样:
(defvar *map* '((0 . "zero") (1 . "one") (2 . "two")))
如何格式化这样吗?
0: zero
1: one
2: two
我想这样(format t "~{~{~a: ~a~}~%~}" *map*)
,而是给出了一个错误,因为“零”不是一个列表,你不能把它的汽车。
当然,这样做(format t "~{~a~%~}" *map*)
打印
(0 . "zero")
(1 . "one")
(2 . "two")
像它应该,但它不是我想要的东西相当。有没有更好的方法来做到这一点,而不仅仅是(dolist (entry *mapping*) (format t "~a: ~a~%" (car entry) (cdr entry)))
?
Freenode上的#CL-园丁通道建议做一个解构循环绑定是这样的:
(loop for (a . b) in *mapping*
do (format t "~a: ~a" a b))
我不认为有更好的方法来做到这一点;我会用map()
:
(format t "~{~a~%~}"
(map 'list
#'(lambda (entry)
(format nil "~a: ~a" (car entry) (cdr entry))
*map*))
你是对的,因为它看起来并不像有什么办法可以挑选除了格式的利弊细胞。
如果定义另一个函数来格式化单一关联:
(defun print-assoc (stream arg colonp atsignp)
(format stream "~A: ~A" (car arg) (cdr arg)))
那么它很简单:
(format t "~{~/print-assoc/~%~}" *map*)
我不知道,如果这是一个进步与否。一方面,它更复杂一点,但另一方面,它确实将打印关联分解为(可重用的)函数,这可能很有用。
你应该在格式中使用合格的函数名。 FORMAT解析* package *中的指定符号,并且在格式被调用时您永远不会知道* package *是什么。 – 2009-08-12 20:51:04
我认为这里的外卖的教训实在是不使用点列表您alists。当然,你可以节省一个反应池,但是你放弃了所有漂亮的顺序和列表功能。这是不值得的。您的格式例子是琐碎完全形成列表:
(defvar *map* '((0 "zero") (1 "one") (2 "two")))
(format t "~:{~a: ~a~}" *map*)
转换的ALIST细胞(a . 2)
使用
(mapcar #'(lambda (x) `(,(car x) ,(cdr x))) *map*)
,然后过程格式列出(a 2)
。
对于例如,要打印((a . 2) (b . 3))
为"a=2&b=3"
使用
(format t "~{~{~a~^=~}~^&~}" (mapcar #'(lambda (x) `(,(car x) ,(cdr x))) *map*))
MAPCAR是多给点... – skypher 2009-08-13 13:22:15