Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate list indices with format directives

Is there a way to get the same output as this: (Hand is a list of cards)

(loop for card in hand
           with i = 1
           do
             (format t "~&~a. ~a~%" i card)
             (incf i))
1. (5 . HEARTS)
2. (5 . CLUBS)
3. (10 . DIAMONDS)
4. (JACK . DIAMONDS)
5. (8 . CLUBS)

but only using one call to format? So far I have this, but I have no idea how to increment the index.

(format nil "~{~%1. ~a~}~%" hand)
1. (5 . HEARTS)
1. (5 . CLUBS)
1. (10 . DIAMONDS)
1. (JACK . DIAMONDS)
1. (8 . CLUBS)

I also tried using a closure alongside the Call Function directive, but you have to reset the counter for every call, and it just feels very kludgey.

(let ((counter 0))
  (defun increment (output-stream format-argument colonp at-sign-p &rest directive-parameters)
    (declare (ignore colonp at-sign-p directive-parameters))
    (incf counter)
    (format output-stream "~a. ~a" counter format-argument))
  (defun reset-counter ()
    (setf counter 0)))

(format t "~&~{~&~/increment/~}" '(a c b d))
1. A
2. C
3. B
4. D
like image 864
user61087 Avatar asked Dec 11 '22 00:12

user61087


1 Answers

Your loop form:

(loop for card in hand
           with i = 1
           do
             (format t "~&~a. ~a~%" i card)
             (incf i))

One usually would write that as:

(loop for card in hand and i from 1
      do (format t "~&~a. ~a~%" i card))

One way to simply deal with the problem is to provide a list with numbers:

(defun numbering (list &key (i0 1))
  (loop for i from i0 and element in list
        collect i collect element))

CL-USER > (format t "~{~%~a. ~a~}~%" (numbering hand))

1. (5 . HEARTS)
2. (5 . CLUBS)
3. (10 . DIAMONDS)
4. (JACK . DIAMONDS)
5. (8 . CLUBS)
NIL
like image 110
Rainer Joswig Avatar answered Dec 26 '22 13:12

Rainer Joswig