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 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 }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.