5

私は Common Lisp を書き始めており、物事をまとめてフォーマットするコツをつかんでいます。

次のような連想リストがあるとします。

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

このようにフォーマットするにはどうすればよいですか?

0: zero
1: one
2: two

のようなことを考えて(format t "~{~{~a: ~a~}~%~}" *map*)いましたが、「ゼロ」はリストではなく、車を取ることができないため、エラーが発生します。

もちろん(format t "~{~a~%~}" *map*)版画もやってます

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

あるべきようですが、私が望んでいるものではありません。これを行うよりも良い方法はあり(dolist (entry *mapping*) (format t "~a: ~a~%" (car entry) (cdr entry)))ますか?

4

5 に答える 5

11

Freenode の #cl-gardeners チャンネルは、次のような破壊ループ バインドを行うことを提案しています。

(loop for (a . b) in *mapping*
  do (format t "~a: ~a" a b))
于 2009-08-12T03:21:32.177 に答える
7

そうです、FORMATからconsセルを分離する方法がないように見えます。

単一の関連付けをフォーマットする別の関数を定義する場合:

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

それなら簡単です:

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

これが改善かどうかはわかりません。一方では、もう少し複雑ですが、他方では、print-assocを(再利用可能な)関数に分割します。これは便利な場合があります。

于 2009-08-12T01:53:54.703 に答える
4

ここで得られる教訓は、連想リストにドット リストを使用しないことだと思います。確かに 1 つのコンス セルを保存しますが、すべての優れたシーケンスとリスト関数を放棄します。それだけの価値はありません。あなたの書式設定の例は、完全に形成されたリストでは簡単です:

(defvar *map* '((0 "zero") (1 "one") (2 "two")))
(format t "~:{~a: ~a~}" *map*)
于 2009-08-12T18:40:00.697 に答える
1

それを行うためのより良い方法はないと思います。私は使用しmap()ます:

(format t "~{~a~%~}"
  (map 'list
    #'(lambda (entry)
      (format nil "~a: ~a" (car entry) (cdr entry))
    *map*))
于 2009-08-12T01:38:41.367 に答える
1

を使用してalistセル(a . 2)をリストに変換します(a 2)

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

フォーマットで処理します。

たとえば、次のように印刷((a . 2) (b . 3))するには"a=2&b=3"

使用する

(format t "~{~{~a~^=~}~^&~}" (mapcar #'(lambda (x) `(,(car x) ,(cdr x))) *map*))
于 2011-09-17T18:44:56.620 に答える