6.3.4 Loop filtering and
ordering
As well as selecting the type of the elements, a loop can
specify extra parameters to filter and order the elements it iterates over.
These parameters are specified by the
where,
orderby and
unique keywords described below. The
keywords may be used alone or together, but when used together they must come in
this order, and will be applied in this order. Also note that
where,
orderby and
unique clauses are run once for each
element, before executing the actual loop.
The where keyword
allows you to add a condition to select only certain elements. A simple form
is:
foreach .objType; where :propName = 'value'
{ /* Operations for the elements */ }Note the semicolon
after the object type, to separate it from the
where keyword. See the
If clause for the full details of the
syntax of conditions.
The orderby
keyword allows you to specify the order in which to iterate over the selected
elements. With no sort criteria specified, elements will be sorted by
type,
name, and
oid. You can give multiple sort
criteria per loop, e.g. sort first by name and then by type:
orderby id, type
Each criterion is a series of
generator commands whose output will form the strings to be compared. The
criteria are separated by commas as seen above.
You can add num
after a criterion to specify numeric comparison:
orderby :count; num, :key; num
You can add
desc to the end of a criterion to
specify descending order, i.e. reverse the sort. The default order can be made
explicit with asc:
orderby :count; num asc, :name; desc
The
unique keyword allows you to specify
one or more uniqueness criteria for loops to avoid handling the same kind of
element multiple times. Each criterion is a series of generator commands whose
output will form the strings which must be unique. For example, assume that you
have a graph of Widgets. Each Widget has a property specifying which Library it
is defined in, and that library must be included. If you want to output the
include statements for the whole graph, without repeatedly including each
library, you can do the following:
foreach .Widget; unique :Library
{ '#include <' :Library '>' newline }Multiple
criteria can be separated by commas, and an element must pass as unique on each
criterion to be accepted. To allow all unique combinations to pass, simply place
both within a single criterion.
If just
unique is
specified with no criteria, elements must be unique (i.e. not the same object
etc., the same as comparing by
oid).
Foreach guarantees this kind of
uniqueness anyway, but with
do you
could for instance be iterating over connected objects, and there could be two
different relationships to the same
object.