2009-08-12 19 views
5

Empiezo a escribir algo sobre Common Lisp y me estoy poniendo manos a la obra para armar las cosas y formatearlas.¿Cómo puedo formatear a una alista en el ceceo común?

Supongamos que tengo una alista, así:

(defvar *map* '((0 . "zero") (1 . "one") (2 . "two"))) 

¿Cómo formateo así?

0: zero 
1: one 
2: two 

que estaba pensando algo así como (format t "~{~{~a: ~a~}~%~}" *map*), pero que da un error porque "cero" no es una lista y no se puede tomar el coche de ella.

Por supuesto, hacer impresiones (format t "~{~a~%~}" *map*)

(0 . "zero") 
(1 . "one") 
(2 . "two") 

como se supone que debe, pero no es exactamente lo que yo quiero. ¿Hay una mejor manera de hacer esto que solo (dolist (entry *mapping*) (format t "~a: ~a~%" (car entry) (cdr entry)))?

Respuesta

10

El canal # CL-jardineros en Freenode sugiere hacer un aprieto bucle de desestructuración de esta manera:

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

No creo que haya una mejor manera de hacerlo; Me utilizado map():

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

mapcar es más que el punto ... – skypher

6

Tienes razón, ya que no parece que haya ninguna manera de machacar a una célula contras de FORMATO.

Si define otra función para dar formato a una sola asociación:

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

entonces es fácil:

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

No estoy seguro si esto es una mejora o no. Por un lado, es un poco más complejo, pero por otro lado, rompe la impresión-asociación en una función (reutilizable), que podría ser útil.

+6

Debe utilizar nombres de función calificados en formato. FORMAT analiza el símbolo especificado en * paquete * y nunca sabrá qué es el * paquete * en el momento en que se llama al formato. –

4

Creo que la lección para llevar aquí realmente no es el uso de listas de puntos para sus listas-A. Ahorras una celda cons, claro, pero renuncias a todas las buenas funciones de secuencia y lista. No vale la pena. Su formato es trivial ejemplo con las listas completamente formados:

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

células convierten la alist (a . 2) a la lista (a 2) usando

(mapcar #'(lambda (x) `(,(car x) ,(cdr x))) *map*) 

y luego procesar en formato.

Por ejemplo., Para imprimir ((a . 2) (b . 3)) como "a=2&b=3"

uso

(format t "~{~{~a~^=~}~^&~}" (mapcar #'(lambda (x) `(,(car x) ,(cdr x))) *map*)) 
Cuestiones relacionadas