2011-01-06 9 views
6

Diese Frage wird wahrscheinlich in einem facepalm enden, aber ich habe es eine Weile versucht und bin immer noch fest, trotz Lesen durch die Hyperspec.Format - Hilfe beim Drucken einer Tabelle

Im Grunde, was ich will, ist, etwas zu tun wie

(format t "~{|~{ ~5d~}|~%~}" '((1 23 2 312) (23 456 1 7890))) 

aber anstelle von Hartcodierung der 5 aus der Liste (Länge des längsten Elements von jeder verschachtelten Liste + 1) zu geben, etwas berechnet werden soll wie

| 1 23  2 312| 
| 23 456  1 7890|  

Vielleicht ich denke hier viel zu kompliziert und es ein einfacherer Weg zu tun, was ich will, aber ich glaube, ich mich in eine mentale Ecke lief, dass ich nicht aus bekommen kann.

+0

Es kann durchaus ein '~' Steuerelement zu tun, was Sie wollen, aber ich würde nur in 2 Schritten tun: Berechnen Sie das breiteste Element, dann erstellen Sie einen Format-String (mit Format!) Mit dem, dann rufen Format zum Erstellen der Tabelle. Es ist also eine 3-Zeilen-Funktion anstelle einer 1-Zeilen-Funktion. :-) – Ken

Antwort

3

die erforderliche Breite zu width gebunden ist Angenommen, dann können Sie dies tun:

(format t "~{|~{ ~Vd~}|~%~}" width '((1 23 2 312) (23 456 1 7890))) 

5 durch V ersetzt wurde und width als Argument wurde FORMAT/

hinzugefügt edit: ursprüngliche Antwort hat die verschachtelten Direktiven nicht korrekt berücksichtigt

In einer Formatregelungszeichenfolge V kann anstelle eines konstanten Werts verwendet werden, um anzuzeigen, dass der entsprechende Wert stattdessen aus der Argumentliste übernommen werden soll.

Sie können dies versuchen:

(setf width 5) 
(setf data '((1 23 2 312) (23 456 1 7890))) 

(format t "~{|~{ ~{~Vd~}~}|~%~}" 
    (mapcar #'(lambda (r) (mapcar #'(lambda (v) (list width v)) r)) data)) 

Dieses Format-String erfordert die gewünschte Breite jeden Wert vorangestellt. Der Ausdruck (mapcar ...) erreicht dies.

+1

+1 Schöne Antwort. Die maximale Breite ist zumindest leicht zu berechnen (zumindest wenn alle Zahlen positiv sind). Zum Beispiel: (1+ (gilt # 'max (mapcar #' (Lambda (x) (Stock (log x 10))) (1 10 100 1000 200000)))). –

+0

Ich habe diese Lösung bewusst abgelehnt, weil Ad-hoc-Spleißen der Breite in die Argumentliste unnötig kompliziert und verschwenderisch für mich scheint. – Svante

+0

+1 und akzeptiert seit "V" war genau das, was ich suchte (und verpasste es wiederholt scheint es). Ich sehe jedoch Swanets Punkt, also +1 auch dort :) –

5

Ich denke, dass haben Sie zwei Möglichkeiten: Lassen Sie die format Magie gehen und andere Schleifenkonstrukte verwenden oder das Format-String selbst erzeugen:

(defun facepalm-printer (lol) 
    (format t (format nil "~~{|~~{ ~~~ad~~}|~~%~~}" 
        (longest-member lol)) 
      lol)) 

Die Definition von longest-member als Übung dem Leser überlassen wird.

Verwandte Themen