Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

common lisp - Looking for format string which allows custom formatting for list of pairs

So I have lists, looking like this:

((24 . 23) (9 . 6) ... )

and want to custom format the output to something looking like this:

"24/23 9/6 ..."

I tried:

(defun show-pair (ostream pair col-used atsign-used) 
  (declare (ignore col-used atsign-used)) 
  (format ostream "~d/~d" (first pair) (second pair)))

(let ((x '( 1 . 2))) (format nil "~{~/show-pair/~^~}" (list x)))

as a simple warming up exercise to show a list with only 1 pair. But when trying this in the emacs slime repl, I get the error

The value 2 is not of type LIST [Condition of type TYPE-ERROR]

Which, of course is confusing as ~/show-pair/ was expected to handle one entry in the list, which is is the pair, passing the pair to show-pair. But it appears, something else is actually happening.

question from:https://stackoverflow.com/questions/65880981/looking-for-format-string-which-allows-custom-formatting-for-list-of-pairs

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you want to do it with format - the problem is to access first and second element of the alist using format directives. I didn't found how I could access them inside a format directive.

However, in such regularly formed structures like an alist, one could flatten the list first and then let format-looping directive consume two elements per looping - then one consumes the pair.

Since the famous :alexandria library doesn't count as dependency in Common Lisp world, one could directly use alexandria:flatten:

(defparameter *al* '((24 . 23) (9 . 6)))
(ql:quickload :alexandria) ;; import alexandria library

(format nil "~{~a/~a~^ ~}" (alexandria:flatten *al*))
;; => "24/23 9/6"

  • nil return as string
  • ~{ ~} loop over the list
  • ~a/~a the fraction
  • ~^ empty space between the elements but not after last element

flatten by the way without :alexandria-"dependency" would be in this case:

(defun flatten (l)
  (cond ((null l) nil)
        ((atom l) (list l))
        (t (append (flatten (car l)) (flatten (cdr l))))))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...