5 Stimmen

Wie kann ich eine Alist in Common Lisp formatieren?

Ich fange gerade an, mir etwas Common Lisp zu schreiben und bekomme gerade den Dreh raus, wie man Dinge zusammenfügt und formatiert.

Nehmen wir an, ich habe eine Liste, etwa diese:

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

Wie kann ich es so formatieren?

0: zero
1: one
2: two

Ich dachte an etwas wie (format t "~{~{~a: ~a~}~%~}" *map*) , aber das führt zu einem Fehler, weil "zero" keine Liste ist und man das Auto nicht daraus nehmen kann.

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

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

wie es sein 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))) ?

11voto

Michael Punkte 766

Der #cl-gardeners-Kanal auf Freenode schlägt vor, eine destrukturierende Schleifenbindung wie diese durchzuführen:

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

7voto

Ken Punkte 5007

Sie haben Recht, es sieht nicht so aus, als gäbe es eine Möglichkeit, eine Cons-Zelle von FORMAT zu trennen.

Wenn Sie eine andere Funktion definieren, um eine einzelne Assoziation zu formatieren:

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

dann ist es ganz einfach:

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

Ich bin mir nicht sicher, ob das eine Verbesserung ist oder nicht. Einerseits ist es ein wenig komplexer, aber andererseits wird print-assoc in eine (wiederverwendbare) Funktion umgewandelt, was nützlich sein könnte.

6 Stimmen

Sie sollten qualifizierte Funktionsnamen im Format verwenden. FORMAT parst das angegebene Symbol in Paket und Sie werden nie wissen, was der Paket zum Zeitpunkt des Aufrufs des Formats.

4voto

dlowe Punkte 161

Ich denke, die Lektion, die man hier mitnehmen kann, ist, dass man keine gepunkteten Listen für seine Listen verwenden sollte. Sie sparen eine Zelle, sicher, aber Sie geben alle netten Sequenz- und Listenfunktionen auf. Das ist es einfach nicht wert. Ihre Formatierung Beispiel ist trivial mit voll ausgebildeten Listen:

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

1voto

Adam Rosenfield Punkte 373807

Ich glaube nicht, dass es einen besseren Weg gibt, es zu tun; ich würde die map() :

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

1voto

Vijayender Punkte 1445

Konvertieren Sie die Zellen der Liste (a . 2) auflisten (a 2) mit

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

und dann im Format verarbeiten.

Zum Beispiel, um zu drucken ((a . 2) (b . 3)) como "a=2&b=3"

verwenden.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X