The foreach instruction accesses entries of a collection sequentially, starting with the first entry and continuing with successive entries until the iteration is terminated.
This section provides the syntax, description, and an example of the foreach instruction, as well as:
Syntax
The syntax of the foreach instruction is:
foreach variable in collection-expression [options] [where condition] do [:label] [foreach-instructions] endforeach [label];
You can specify the reversed or discreteLock option, or both reversed and discreteLock. If you specify both options, you must separate the values with a comma. See also "Iterating over a Range of Numeric Values", later in this section, for details about the collection‑expression syntax when executing a sequence of statements a number of times.
Description
You can nest foreach instructions within each other to any level.
The reversed option enables elements of a collection to be accessed in a reverse direction, starting with the last entry and then successive prior entries until the first element is reached. (For details of iterating backwards through collections, see "Using Iterators in Collections", later in this chapter.)
The discreteLock option specifies that a shared lock is not retained for the duration of the foreach instruction. The collection is share locked only for the period during which the foreach instruction is retrieving a snapshot of entries from the associated collection.
The optional where clause, if present, contains a
If the discreteLock option is not specified, execution of a foreach iteration attempts to acquire an implicit shared lock on the collection being iterated, so the foreach may wait for concurrent users with exclusive locks on the collection. The shared lock ensures that concurrent users cannot add or delete entries from the collection for the duration of the foreach loop. The lock is released at the end of the foreach loop.
As a foreach instruction implicitly locks a collection that is being iterated, if you attempt to add or remove collection members from a serverExecution method while in a foreach loop on a client method that iterates through the collection, an exception is raised.
The break instruction can be used to terminate a foreach loop prematurely or the continue instruction can be used to cause the next iteration of a foreach loop to begin.
The optional :label identifier is used by break instructions and continue instructions to nominate the specific loop that is to be terminated or continued in a group of nested foreach loops. For more details, see "break Instruction" or "continue Instruction", later in this chapter.
Examples
The following example uses a foreach loop to write out the names and ages of all employees in a supplied employee dictionary. In this example, the calculateAge is a method on the Employee class that returns an integer value of the employee's age.
writeEmployees(employees: EmployeeDict); vars emp : Employee; begin foreach emp in employees do write emp.name & ", " & emp.calculateAge.String & " years old"; endforeach; end;
The following example uses a foreach loop with a where clause to write out the names of all employees in a supplied employee dictionary who are older than a specified age.
writeEmployeesOlderThanAge(employees: EmployeeDict; minimumAge: Integer); vars emp : Employee; begin foreach emp in employees where emp.calculateAge > minimumAge do write emp.name; endforeach; end;