foreach Instruction

The foreach instruction accesses entries of a collection sequentially, starting with the first entry and continuing with successive entries until the iteration is terminated.

With the release of Jade version 2020.0.01 and higher, the foreach instruction has been extended to support iterating with the JadeIterableIF interface.

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 iterable-expression [as type‑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:

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 Boolean expression that must evaluate to true to allow the optional foreach-instructions to be executed.

The optional as clause, if present, contains an explicit type name or an expression that must evaluate to a type, which enables the foreach target variable to be a subtype of the collection membership. (For details of using an as clause, see "Using an as Clause in foreach Instructions", later in this chapter.)

The shared lock and discreteLock semantics may not apply when iterating an object implementing a JadeIterableIF interface. For details, see "Iterating using the JadeIterableIF interface".

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;