2009-08-12 50 views
5

我开始给我写一些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)))

回答

10

Freenode上的#CL-园丁通道建议做一个解构循环绑定是这样的:

(loop for (a . b) in *mapping* 
    do (format t "~a: ~a" a b)) 
1

我不认为有更好的方法来做到这一点;我会用map()

(format t "~{~a~%~}" 
    (map 'list 
    #'(lambda (entry) 
     (format nil "~a: ~a" (car entry) (cdr entry)) 
    *map*)) 
+0

MAPCAR是多给点... – skypher 2009-08-13 13:22:15

6

你是对的,因为它看起来并不像有什么办法可以挑选除了格式的利弊细胞。

如果定义另一个函数来格式化单一关联:

(defun print-assoc (stream arg colonp atsignp) 
    (format stream "~A: ~A" (car arg) (cdr arg))) 

那么它很简单:

(format t "~{~/print-assoc/~%~}" *map*) 

我不知道,如果这是一个进步与否。一方面,它更复杂一点,但另一方面,它确实将打印关联分解为(可重用的)函数,这可能很有用。

+6

你应该在格式中使用合格的函数名。 FORMAT解析* package *中的指定符号,并且在格式被调用时您永远不会知道* package *是什么。 – 2009-08-12 20:51:04

4

我认为这里的外卖的教训实在是不使用点列表您alists。当然,你可以节省一个反应池,但是你放弃了所有漂亮的顺序和列表功能。这是不值得的。您的格式例子是琐碎完全形成列表:

(defvar *map* '((0 "zero") (1 "one") (2 "two"))) 
(format t "~:{~a: ~a~}" *map*) 
1

转换的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*)) 
相关问题