2011-01-06 7 views
6

この質問はおそらくfacepalmで終わりますが、私はしばらく試してみましたが、ハイパースペックを読んでいてもまだ固執しています。形式 - テーブルを印刷するのに役立つ

は基本的に私は何をしたい

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

のようなものではなく、ハードコーディング、それはリストから計算しなければならない5(任意のネストされたリスト+ 1から最長要素の長さ)を得たものです以下のような

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

たぶん私はここにあまりにも複雑で考えていますし、私が欲しいものを行うための簡単な方法がありますが、私は、私はから抜け出すことができない精神的なコーナーに自分自身を走ったと思います。

+0

あなたがしたいことをするための '〜'コントロールがあるかもしれませんが、私は2つのステップでこれをやっています:最も広い要素を計算し、それを使ってフォーマット文字列を作成してからフォーマットを使用してテーブルを構築します。つまり、1行の関数ではなく3行の関数です。 :-) – Ken

答えて

3

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

5Vwidthに置き換えられていますが FORMAT/

への引数として追加されました編集:元の答えは、ネストされた指示を正しく説明していませんでした

フォーマット制御文字列Vは、定数値の代わりに使用できます。これは、代わりに対応する値が引数リストから取得されることを示します。

あなたはこれを試すことができます。

(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)) 

このフォーマット文字列は、それぞれの値の前に所望の幅が必要です。 (mapcar ...)式がこれを達成します。

+1

+1良い答え。最大幅は少なくとも計算が簡単です(少なくともすべての数値が正の場合)。たとえば、 '(1 +(apply# 'max(mapcar#'(lambda(x)(floor(log x 10))) '(1 10 100 1000 200000)))' 'を適用します。 –

+0

私は、この解決策を拒否しました。なぜなら、引数リストに幅をスプライシングすることは、不必要に複雑で無駄に思えるからです。 – Svante

+0

+1そして 'V'が私が探していたものであり(繰り返し見逃していたので)、受け入れられました。私はSvanetのポイントも見ていますので、+1もあります:) –

5

私は次の2つのオプションを持っていると思います:format魔法が行くと使用する他のループ構造をまたはフォーマット文字列自体を生成してみましょう:

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

longest-memberの定義は読者への課題として残されています。そして、あなたがこれを行うことができ、必要な幅がwidthにバインドされていると仮定すると、

関連する問題