Next: , Previous: Alist and Plist Examples, Up: LOOP --> Loopless


2.2 COLLECTING/WITH-COLLECTORS Examples

Here's two alternatives to loop you can use when you need to both collect into and nconc onto a fresh list:

     (collecting
       (dolist (element '(a 24 x y 86 "test" (nested stuff)))
         (typecase element
           (symbol (collect element))
           (number (collect (- element)))
           (list (ncollect (copy-seq element))))))
     ==
     (mapcan (lambda (element)
               (typecase element
                 (symbol (list element))
                 (number (list (- element)))
                 (list (copy-seq element))))
             '(a 24 x y 86 "test" (nested stuff)))
     ==
     (loop for element in '(a 24 x y 86 "test" (nested stuff))
           if (symbolp element)
             collect element
           else if (numberp element)
                  collect (- element)
           else if (listp element)
                  nconc (copy-seq element))
     ⇒ (A -24 X Y -86 NESTED STUFF)

Here's how to use with-collectors to collect into different lists simultaneously. Notice how we can use etypecase because we don't have to conform to loop's syntax (it's true that iterate, an alternative to loop, doesn't have that problem).

     (with-collectors (symbols numbers strings)
       (dovector (element #(a 24 b "test" 86 "this" c))
         (etypecase element
           (symbol (symbols element))
           (number (numbers element))
           (string (strings element)))))
     ==
     (loop for element across #(a 24 b "test" 86 "this" c)
           if (symbolp element)
             collect element into symbols
           else if (numberp element)
                  collect element into numbers
           else if (stringp element)
                  collect element into strings
           finally (return (values symbols numbers strings)))
     ⇒
     (A B C)
     (24 86)
     ("test" "this")