# Iterators
> [HTML Version](iterators.htm)
_Updated February 2025_
To access elements from a collection without knowing the specific keys, an “iterator” iterator is used. Iterators are special variables which receive the value of the next element of a collection each time through the loop.
To iterate through a collection, a [FOREACH](foreach.htm.md) loop is used:
foreach \$\$i in \$aryname(\{startkey,\{endkey\}\}) \! fwd iterator
print \$\$i \! print the element value
print .key(\$\$i) \! print the element key
next \$\$i
foreach’reverse \$\$j in \$aryname(\{startkey,\{endkey\}\}) \! reverse iterator
print \$\$j \! print the element value
print .key(\$\$j) \! print the element key
next \$\$j
See [Special ORDMAP Functions](specialordmapfunctions.htm.md) for a description of the .KEY() and other related functions.
The optional _startkey_ and _endkey_ values may be any kind of expressions that could appear on the right side of an assignment statement (aka "rvalues"), i.e. literals, variables, expressions with USING, function calls, etc. Numeric values are converted to string format, truncating to integer. Note that if there is not an exact match on _startkey_, the loop will iterator zero times, unlike in an ISAM lookup, where a failed initial key match will nevertheless affect the subsequent next operation. See History below for chronology of refinements.
Note: the above examples assume varstr elements; for varx elements, you wouldn’t try to print the \$\$i or \$\$j iterator values directly; instead you would assign them to a structure and then access the members, i.e.
Prodstruct = \$\$i \! copy iterator value to structure
print Prodstruct.field \! print a field of the element value
print .key(\$\$j) \! print the element key
Although this is similar to a standard for/next loop, there are some noteworthy differences:
• First, unlike the standard _for/next_ loop where the loop variable must have been previously defined, in the FOREACH loop, the iterator variable (_\$\$i_ in the example above) is created on the fly and exists just for the duration of the loop. Iterator variables must all start with \$\$ (which should not be used for any other variable type.) Since it is destroyed at the end of the loop, the same iterator variable name can be used in other FOREACH loops.
• Unlike the standard for/next loop, here the starting and ending values are optional; if omitted, the are effectively interpreted as the first and last items in the collection. The concept is similar to sequencing through an indexed file from a starting key (or one end of the file) to an ending key (or the opposite end of the file), except that if there is not an exact match on startkey, the entire loop will be skipped. To iterate the entire collection, use empty parens, e.g. \$aryname().
• The order of the sequence will be according to the key, either forward (foreach) or reverse (foreach'reverse).
• Modifications to the collection index (including deleting key-value pairs) during iteration should be strictly avoided. See [Writeable Iterators](writableiterators.htm.md) for details.
**See Also**
• [FOREACH](foreach.htm.md)
**History**
2023 November, A-Shell 7.0.1752.0: _endkey_ parameter extended to gridmaps.
2023 October, A-Shell 7.0.1751.0: _startkey_ support added to FOREACH'REVERSE; _endkey_ added for ordered map iteration.
2023 August, A-Shell 6.5.1739: In FOREACH, if the specified starting key is not found, the iteration now starts with the next key. Previously, the result would have been an empty iteration. In FOREACH'REVERSE, the starting key is now recognized whereas previously it was ignored. As with FOREACH, if not found, the iteration starts with the next key—i.e. the next one lower in the collating sequence.
2018 May, A-Shell 6.5.1636, compiler edit 859: the starting key in a FOREACH statement may now be any kind of expression. Previously, it only allowed a simple variable or a literal string or numeric constant; numeric literals were allowed but weren't converted to string and thus typically failed to match any items in the map.
**Subtopics**
- [Writable Iterators](writableiterators.htm.md)