Indexing Clause (LOOP-END LOOP command)

The indexing clause limits the number of iterations for a loop by specifying the number of times the program should execute commands within the loop structure. The indexing clause is specified on the LOOP command and includes an indexing variable followed by initial and terminal values.

  • The program sets the indexing variable to the initial value and increases it by the specified increment each time the loop is executed for a case. When the indexing variable reaches the specified terminal value, the loop is terminated for that case.
  • By default, the program increases the indexing variable by 1 for each iteration. The keyword BY overrides this increment.
  • The indexing variable can have any valid variable name. Unless you specify a scratch variable, the indexing variable is treated as a permanent variable and is saved in the active dataset. If the indexing variable is assigned the same name as an existing variable, the values of the existing variable are altered by the LOOP structure as it is executed, and the original values are lost. See the topic Creating Data (LOOP-END LOOP command) for more information.
  • The indexing clause overrides the maximum number of loops specified by SET MXLOOPS.
  • The initial and terminal values of the indexing clause can be numeric expressions. Noninteger and negative expressions are allowed.
  • If the expression for the initial value is greater than the terminal value, the loop is not executed. For example, #J=X TO Y is a zero-trip loop if X is 0 and Y is –1.
  • If the expressions for the initial and terminal values are equal, the loop is executed once. #J=0 TO Y is a one-trip loop when Y is 0.
  • If the loop is exited via BREAK or a conditional clause on the END LOOP statement, the iteration variable is not updated. If the LOOP statement contains both an indexing clause and a conditional clause, the indexing clause is executed first, and the iteration variable is updated regardless of which clause causes the loop to terminate.

Example

LOOP #I=1 TO 5. /*LOOP FIVE TIMES
COMPUTE X=X+1.
END LOOP.
  • The scratch variable #I (the indexing variable) is set to the initial value of 1 and increased by 1 each time the loop is executed for a case. When #I increases beyond the terminal value 5, no further loops are executed. Thus, the value of X will be increased by 5 for every case.

Example

LOOP #I=1 TO 5 IF (Y GT 10). /*Loop to X=5 only if Y GT 10
COMPUTE X=X+1.
END LOOP.
  • Both an indexing clause and an IF clause are specified on LOOP. X is increased by 5 for all cases where Y is greater than 10.

Example

LOOP #I=1 TO Y. /*Loop to the value of Y
COMPUTE X=X+1.
END LOOP.
  • The number of iterations for a case depends on the value of the variable Y for that case. For a case with value 0 for the variable Y, the loop is not executed and X is unchanged. For a case with value 1 for the variable Y, the loop is executed once and X is increased by 1.

Example

* Factorial routine.
 
DATA LIST FREE / X.
BEGIN DATA
1 2 3 4 5 6 7
END DATA.
 
COMPUTE FACTOR=1.
LOOP #I=1 TO X.
COMPUTE FACTOR=FACTOR * #I.
END LOOP.
LIST.
  • The loop structure computes FACTOR as the factorial value of X.

Example

* Example of nested loops: 
  compute every possible combination of values for each variable.
 
INPUT PROGRAM.
-LOOP #I=1 TO 4. /* LOOP TO NUMBER OF VALUES FOR I
- LOOP #J=1 TO 3. /* LOOP TO NUMBER OF VALUES FOR J
-  LOOP #K=1 TO 4. /* LOOP TO NUMBER OF VALUES FOR K
-   COMPUTE I=#I.
-   COMPUTE J=#J.
-   COMPUTE K=#K.
-   END CASE.
-  END LOOP.
- END LOOP.
-END LOOP.
END FILE.
END INPUT PROGRAM.
LIST. 
  • The first loop iterates four times. The first iteration sets the indexing variable #I equal to 1 and then passes control to the second loop. #I remains 1 until the second loop has completed all of its iterations.
  • The second loop is executed 12 times, three times for each value of #I. The first iteration sets the indexing variable #J equal to 1 and then passes control to the third loop. #J remains 1 until the third loop has completed all of its iterations.
  • The third loop results in 48 iterations (4 × 3 × 4). The first iteration sets #K equal to 1. The COMPUTE statements set the variables I, J, and K each to 1, and END CASE creates a case. The third loop iterates a second time, setting #K equal to 2. Variables I, J, and K are then computed with values 1, 1, 2, respectively, and a second case is created. The third and fourth iterations of the third loop produce cases with I, J, and K, equal to 1, 1, 3 and 1, 1, 4, respectively. After the fourth iteration within the third loop, control passes back to the second loop.
  • The second loop is executed again. #I remains 1, while #J increases to 2, and control returns to the third loop. The third loop completes its iterations, resulting in four more cases with I equal to 1, J to 2, and K increasing from 1 to 4. The second loop is executed a third time, resulting in cases with I=1, J=3, and K increasing from 1 to 4. Once the second loop has completed three iterations, control passes back to the first loop, and the entire cycle is repeated for the next increment of #I.
  • Once the first loop completes four iterations, control passes out of the looping structures to END FILE. END FILE defines the resulting cases as a data file, the input program terminates, and the LIST command is executed.
  • This example does not require a LEAVE command because the iteration variables are scratch variables. If the iteration variables were I, J, and K, LEAVE would be required because the variables would be reinitialized after each END CASE command.

Example

* Modifying the loop iteration variable.
 
INPUT PROGRAM.
PRINT SPACE    2.
LOOP           A = 1 TO 3. /*Simple iteration
+  PRINT          /'A WITHIN LOOP: ' A(F1).
+  COMPUTE        A = 0.
END LOOP.
PRINT          /'A AFTER LOOP:  ' A(F1).
 
NUMERIC        #B.
LOOP           B = 1 TO 3. /*Iteration + UNTIL
+  PRINT          /'B WITHIN LOOP: ' B(F1).
+  COMPUTE        B = 0.
+  COMPUTE        #B = #B+1.
END LOOP       IF #B = 3.
PRINT          /'B AFTER LOOP:  ' B(F1).
 
NUMERIC        #C.
LOOP           C = 1 TO 3 IF #C NE 3. /*Iteration + WHILE
+  PRINT          /'C WITHIN LOOP: ' C(F1).
+  COMPUTE        C = 0.
+  COMPUTE        #C = #C+1.
END LOOP.
PRINT          /'C AFTER LOOP:  ' C(F1).
 
NUMERIC        #D.
LOOP           D = 1 TO 3. /*Iteration + BREAK
+  PRINT          /'D WITHIN LOOP: ' D(F1).
+  COMPUTE        D = 0.
+  COMPUTE        #D = #D+1.
+  DO IF          #D = 3.
+     BREAK.
+  END IF.
END LOOP.
PRINT          /'D AFTER LOOP:  ' D(F1).
 
LOOP           E = 3 TO 1. /*Zero-trip iteration
+  PRINT          /'E WITHIN LOOP: ' E(F1).
+  COMPUTE        E = 0.
END LOOP.
PRINT          /'E AFTER LOOP:  ' E(F1).
END FILE.
END INPUT PROGRAM.
EXECUTE.
  • If a loop is exited via BREAK or a conditional clause on the END LOOP statement, the iteration variable is not updated.
  • If the LOOP statement contains both an indexing clause and a conditional clause, the indexing clause is executed first, and the actual iteration variable will be updated regardless of which clause causes termination of the loop.

The output from this example is shown below.

Figure 1. Modifying the loop iteration value

A WITHIN LOOP: 1
A WITHIN LOOP: 2
A WITHIN LOOP: 3
A AFTER LOOP:  4
B WITHIN LOOP: 1
B WITHIN LOOP: 2
B WITHIN LOOP: 3
B AFTER LOOP:  0
C WITHIN LOOP: 1
C WITHIN LOOP: 2
C WITHIN LOOP: 3
C AFTER LOOP:  4
D WITHIN LOOP: 1
D WITHIN LOOP: 2
D WITHIN LOOP: 3
D AFTER LOOP:  0
E AFTER LOOP:  3