LOOP( dataset [ ,loopcount ][ ,loopfilter ][ ,loopcondition ] , loopbody [, UNORDERED | ORDERED( bool ) ] [, STABLE | UNSTABLE ] [,ALGORITHM( name ) ][, FEW] )
The LOOP function iteratively performs the loopbody operation. The COUNTER keyword is implicitly available for use to return the current iteration.
The loopcount, loopfilter, and loopcondition parameters are all optional, but at least one of the three must be present.
For each successive iteration, the input dataset (expressed as ROWS(LEFT) as the parameter to the loopbody) is the result set of the previous iteration after application of any loopfilter. The final result of the LOOP returns all records that completed processing, no matter which iteration that completion occurred (not just the result set from the final iteration).
Example:
namesRec := RECORD
STRING20 lname;
STRING10 fname;
UNSIGNED2 age := 25;
UNSIGNED2 ctr := 0;
END;
namesTable := DATASET([{'Flintstone','Fred',35},
{'Flintstone','Wilma',43},
{'Jetson','Georgie',10},
{'Mr. T','Z-man'}], namesRec);
BodyFunc(DATASET(namesRec) ds, UNSIGNED4 c) :=
PROJECT(ds,
TRANSFORM(namesRec,
SELF.age := LEFT.age*c;
SELF.ctr := COUNTER*c ;
SELF := LEFT));
/* Form 1 -- LOOP(ds, loopcount, loopbody)
Processes loopcount times, basically a "for loop" construct.
This example also demonstrates the two possible scopes of the COUNTER
keyword within a LOOP:
* The COUNTER in the LOOP function (passed to BodyFunc) is the number
of iterations the LOOP has done.
* The COUNTER in the TRANSFORM for the PROJECT in the BodyFunc counts
the number of records processed by the current iteration of PROJECT.
*/
Form1 := LOOP(namesTable,
2, //iterate 2 times
ROWS(LEFT) & BodyFunc(ROWS(LEFT),COUNTER)); //16 rows
OUTPUT(Form1,NAMED('Form1_example'));
/* Form 2 -- LOOP(ds, loopfilter, loopbody)
Continues processing while the loopfilter expression is TRUE for any
records in ROWS(LEFT). This is basically a "while loop" construct. The
loopfilter expression is evaluated on the entire set of ROWS(LEFT)
records prior to each iteration.
*/
Form2 := LOOP(namesTable,
LEFT.age < 100, //process only recs where TRUE
PROJECT(ROWS(LEFT),
TRANSFORM(namesRec,
SELF.age := LEFT.age*2;
SELF := LEFT)));
OUTPUT(Form2,NAMED('Form2_example'));
/* Form 3 -- LOOP(ds, loopcondition, loopbody)
Continues processing while the loopcondition expression is TRUE.
This is basically a "while loop" construct. The loopcondition expression
is evaluated on the entire set of ROWS(LEFT) records prior to each
iteration.
*/
Form3 := LOOP(namesTable,
SUM(ROWS(LEFT), age) < 1000 * COUNTER,
PROJECT(ROWS(LEFT),
TRANSFORM(namesRec,
SELF.age := LEFT.age*2;
SELF := LEFT)));
OUTPUT(Form3,NAMED('Form3_example'));
/* Form 4 -- LOOP(ds, loopcount, loopfilter, loopbody)
Processes loopcount times, with the loopfilter expression
defining when each record continues to process through the loopbody
expression. This is basically a "for loop" construct with a filter
specifying which records are processed each iteration.
*/
Form4 := LOOP(namesTable,
10,
LEFT.age < 100, //process only recs where TRUE
BodyFunc(ROWS(LEFT), COUNTER));
OUTPUT(Form4,NAMED('Form4_example'));
/* Form 5 -- LOOP(ds, loopcount, loopcondition, loopbody)
Processes loopcount times, with the loopcondition expression
defining the set of records that continue to process through the loopbody
expression. This is basically a "for loop" construct with a filter
specifying the record set processed for each iteration.
This example also demonstrates the two possible scopes of the COUNTER
keyword within a LOOP:
* The COUNTER in the LOOP function's loopfilter expression is the number
of recursive iterations the LOOP has done.
* The COUNTER in the TRANSFORM for the PROJECT counts the number of records
processed by the current iteration of PROJECT.
*/
Form5 := LOOP(namesTable,
10, //iterate 10 times
LEFT.age * COUNTER <= 200, //process only recs where TRUE
PROJECT(ROWS(LEFT),
TRANSFORM(namesRec,
SELF.age := LEFT.age*2,
SELF.ctr := COUNTER,
SELF := LEFT)));
OUTPUT(Form5,NAMED('Form5_example'));
/* Form 6 -- LOOP(ds, loopfilter, loopcondition, loopbody)
Continues processing while the loopcondition expression is TRUE.
Records where the loopfilter expression is TRUE continue processing.
This is basically a "while loop" construct with individual record
processing continuation logic.
*/
Form6 := LOOP(namesTable,
LEFT.age < 100,
EXISTS(ROWS(LEFT)) and SUM(ROWS(LEFT), age) < 1000,
BodyFunc(ROWS(LEFT), COUNTER));
OUTPUT(Form6,NAMED('Form6_example'));
/* Form 7 -- LOOP(ds, loopcount, loopfilter, loopcondition, loopbody)
Continues processing while the loopcondition expression is TRUE.
Records where the loopfilter expression is TRUE continue processing.
This is basically a "while loop" construct with individual record
processing continuation logic.
*/
Form7 := LOOP(namesTable,
10,
LEFT.age < 100,
EXISTS(ROWS(LEFT)) and SUM(ROWS(LEFT), age) < 1000,
BodyFunc(ROWS(LEFT), COUNTER));
OUTPUT(Form7,NAMED('Form7_example'));
See Also: GRAPH