
2.9 Advanced iteration
{for|as} var [type-spec]being {each|the} loop-method-name
[in|of]
[preposition expression]*
The var argument takes on the value of each element in the data structure expression by using the loop method specified by the loop-method-name argument. The data type of var can be specified by the type-spec argument.
For the purposes of readability, the loop keywordeach should follow the loop keywordbeing when the reference to the elements in the data structure is singular. The loop keywordthe is used afterbeing when a plural reference to the elements of the data structure is made in the loop method. These keywords are syntactically equivalent; you can useeach with plural references andthe with singular references without causing an error.
Iteration stops when there are no more elements in the specified expression that can be referenced in the way defined by the specified loop method.
For each loop method, there is a set of allowable prepositions; the most common prepositions areof andin. All of the prepositions listed under "Syntax 1" of {for|as} in Section 2.2 on page 12 are also allowed. Also, for the purposes of parsing these advanced iteration constructs, the loop keywordusing is treated as a preposition.
The loop-method-name argument can be one of the following methods; the singular and plural forms are interchangeable:
elt. Common Lisp sequences include lists, vectors, and strings. You can use the macrodefloop to define an additional form of sequential iteration; see Section 2.10 on page 49
the is wrapped around the expression to be iterated over, the Compiler recognizes it as a declaration. In particular, by usingthe withelements, you can declare array types within the Loop Facility. Arrays declared to be simple, with known rank and element types, are especially optimized by Liquid Common Lisp.
;; Print the elements of a list.
> (loop for x being the elements of '(1 2 3)
do (print x))
1
2
3
NIL
;; Print the elements of a vector up to a particular index.
> (loop for x being the elements of #(a b c d e) to 3
do (print x))
A
B
C
D
NIL
;; Print the characters in a string, which is also a vector.
> (loop for x being the elements of "abcde" from 2
do (print x))
#\c
#\d
#\e
NIL
;; Print the elements of a bit vector.
> (loop for x being the elements of #*101
do (print x))
1
0
1
NIL
; Since the loop type-spec syntax is not rich enough to specify
; all of the refinements possible over sequences, you can use the
; Common Lisp THE construct around the sequence expression.
> (setq z "abc")
"abc"
> (loop for x being the elements of (the simple-string z)
do (print x))
#\a
#\b
#\c
NIL
(the array array-name) as the sequence argument for anelements method.
;; Seed an array with values, and return all of the values
;; in the array.
> (let ((array (make-array 10)))
(loop for i from 0 to 9
do (setf (aref array i) i))
(loop for a being the array-elements of array
collect a))
(0 1 2 3 4 5 6 7 8 9)
;; Print the elements of a bit vector, which is a one-dimensional
;; array.
> (loop for x being the array-elements of #*101 do (print x))
1
0
1
NIL
;; Print the elements of a string, which is a one-dimensional
;; array.
> (loop for x being the array-elements of "fun" do (print x))
#\f
#\u
#\n
NIL
value in ausing construct with one of these loop methods, the iteration can optionally access the keyed value. The order in which the keys are accessed is undefined; empty slots in the hash table are ignored.
;; Create a hash table, and put some values in it. Count the
;; number of odd keys in the table, and then collect both the keys
;; and values into an alternating list.
> (setq *ht* (make-hash-table))
#<Hash-Table 59C5AB>
> (loop for i from 1 to 10
do (setf (gethash i *ht*) (format nil "~D" i)))
NIL
> (loop for k being the hash-keys of *ht*
when (oddp k) count k)
5
> (loop for integer being the hash-keys of *ht* using (value string)
nconc (list integer string))
(1 "1" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9" 10 "10")
key in ausing construct with one of these loop methods, the iteration can optionally access the key that corresponds to the value. The order in which the keys are accessed is undefined; empty slots in the hash table are ignored.
;;; Create a hash table, and put some values in it. Count the ;;; number of values of length greater than 1, and then collect ;;; both the keys and values into an alternating list. > (setq *ht* (make-hash-table)) #<Hash-Table 59C5AB>> (loop for i from 1 to 10 do (setf (gethash i *ht*) (format nil "~D" i))) NIL
> (loop for str being the hash-values of *ht* count (> (length str) 1)) 1
> (loop for string being the hash-values of *ht* using (key integer) nconc (list integer string)) (1 "1" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9" 10 "10")
find-package are specified. If you do not specify the package for the iteration, the current package is used. If you specify a package that does not exist, an error is signaled.
;; Count the symbols in a new package, which should be empty.
> (let ((pkg (make-package (gensym))))
(loop for s being each present-symbol in pkg count s))
0
find-package. If you do not specify the package for the iteration, the current package is used. If you specify a package that does not exist, an error is signaled.
;; Gather symbols in a new package, which inherits from the
;; LISP package.
> (let ((pkg (make-package (gensym))))
(loop for s being each symbol in pkg collect s))
(POSITION PUSHNEW READ-FROM-STRING...)
find-package. If you do not specify the package for the iteration, the current package is used. If you specify a package that does not exist, an error is signaled.
;; Gather external symbols in a new package with a few entries.
> (let ((pkg (make-package "TEMP")))
(intern "A" pkg)
(export (intern "B" pkg) pkg)
(intern "C" pkg)
(loop for s being the external-symbols in pkg collect s))
TEMP:B
defloop ordefine-loop-method. See Section 2.10 on page 49 for more information about these macros.

Generated with Harlequin WebMaker