common lisp - Does FORMAT provide a counter for lists iteration -
i want output lists , print position in list e.g.
'(a b c)
become "1:a 2:b 3:c"
as format
supports iterating on given list, wondering whether provides sort of counting directive?
e.g. format
string this: "~{~@c:~a~}"
whereas ~@c
counter.
if want boring answer, here go:
(format t "~:{~a:~a ~}" (loop 0 e in '(x y z) collect (list e)))
and more interesting one! @renzo's answer, uses tilde directive achieve work.
(defvar *count* 0) (defvar *printer* "~a") (defun iterate-counting (stream arg c at) (declare (ignore c)) (let ((*count* (if @ -1 0))) (destructuring-bind (*printer* delimiter &rest args) arg (format stream (format nil "~~{~~/iterate-piece/~~^~a~~}" delimiter) args)))) (defun iterate-piece (stream arg &rest dc) (declare (ignore dc)) (incf *count*) (format stream *printer* *count* arg))
this uses 2 special variables make both thread-safe , allow nesting. won't it's handy use though. first item of argument list has format string denotes how print argument , counter. such format list, first argument counter, , second argument actual item list. can switch around if need using asterisk directive. second item should string print delimiter between each item. finally, rest of list has actual items print.
(format t "~/iterate-counting/" '("~a:~a" " " x y z)) => 1:x 2:y 3:z (format t "~/iterate-counting/" '("~a:~/iterate-counting/" " " ("~a>~a" "," 0 1 2) ("~a>~a" "," b c) ("~a>~a" "," x y z))) => 1:1>0,2>1,3>2 2:1>a,2>b,3>c 3:1>x,2>y,3>z
if want start counting zero, add @
modifier iterate-counting
:
(format t "~@/iterate-counting/" '("~a:~a" " " x y z)) => 0:x 1:y 2:z
i wouldn't use this, it's far less obvious going on if stumble across directive uninitiated. less confusing potential future reader write tailored function this, trying ab/use format
.
Comments
Post a Comment