2009-08-12 7 views
5

Ich fange an, mir etwas Common Lisp zu schreiben und bin gerade dabei, Dinge zusammen zu fassen und zu formatieren.Wie kann ich einen Alist in Lispeln formatieren?

Nehmen wir an, ich habe eine alist, wie folgt aus:

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

Wie formatiere ich es so?

0: zero 
1: one 
2: two 

Ich dachte so etwas wie (format t "~{~{~a: ~a~}~%~}" *map*), aber das gibt einen Fehler, da „Null“ keine Liste ist, und Sie können das Auto nicht nehmen.

Natürlich tun (format t "~{~a~%~}" *map*) druckt

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

wie es soll, aber es ist nicht ganz das, was ich will. Gibt es einen besseren Weg dies zu tun als nur (dolist (entry *mapping*) (format t "~a: ~a~%" (car entry) (cdr entry)))?

Antwort

10

Der # cl-Gärtner-Kanal auf Freenode eine Destrukturierung Schleife binden wie dies legt nahe tun:

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

Ich glaube nicht, dass es einen besseren Weg gibt;

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

mapcar auf den Punkt drucken ... mehr – skypher

6

Du hast Recht, dass es nicht so aussieht es eine Möglichkeit ist, eine cons Zelle von FORMAT auseinander zu nehmen: Ich würde map() verwendet.

Wenn Sie eine andere Funktion definieren eine einzige Assoziation zu formatieren:

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

dann ist es einfach:

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

Ich bin mir nicht sicher, ob dies eine Verbesserung ist oder nicht. Auf der einen Seite ist es ein wenig komplexer, auf der anderen Seite bricht es jedoch die Druckassoziation zu einer (wiederverwendbaren) Funktion aus, was nützlich sein könnte.

+6

Sie sollten qualifizierte Funktionsnamen im Format verwenden. FORMAT analysiert das angegebene Symbol in * package * und Sie werden nie wissen, was das * Paket * zum Zeitpunkt des Aufrufs des Formats ist. –

4

Ich denke, die hier zum Mitnehmen Lektion ist wirklich nicht gepunktete Listen für Ihre Alists zu verwenden. Sie sparen eine Cons-Zelle, sicher, aber Sie geben alle netten Sequenz- und Listenfunktionen auf. Es ist einfach nicht wert. Ihre Formatierung Beispiel ist trivial mit voll Listen gebildet:

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

die (a . 2) alist Zellen konvertieren (a 2) zur Liste

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

und anschließend Prozess im Format.

Für zB., ((a . 2) (b . 3)) als "a=2&b=3"

Verwendung

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