One of the most important tasks that a computer can do it repetition of tasks. That’s why iteration is such an important element of JSL code. In version 16 of JMP, new syntax was introduced to describe the way we iterate over elements of structures such as lists and matrices.
The new syntax of iteration is based on the for each function. The documentation for this function describes its use for iterating over elements of ‘containers’. A container is just an abstract name for something that contains a collection of items: most commonly lists, but also matrices and associative arrays.
Example 1.1 Traditional for-loop
Here is an example of the traditional use of a for-loop in JSL:
1 2 3 4 5 6 |
lstAges = {12,13,14}; for (i=1,i<=nitems(lstAges),i++, age = lstAges[i]; show(age) ); |
Output:
1 2 3 |
age = 12 age = 13 age = 14 |
Example 1.2 Iterating through elements of a list using ‘for each’
1 2 3 4 |
lstAges = {12,13,14}; for each( {age},lstAges, show(age) ); |
Output:
1 2 3 |
age = 12 age = 13 age = 14 |
Example 1.3 Iterating through elements of a data table column
1 2 3 4 5 6 |
dt = data table("Big Class"); heights = dt:height << get values; for each( {height},heights, show(height) ); |
Example 2.1 transforming elements using a traditional for-loop
In example 1.3 above the height measurements are in inches. Do people really still l use inches? Let’s convert to centimetres:
1 2 3 4 |
newHeights = {}; for (i=1,i<=nrows(heights),i++, newHeights[i] = 2.54 * heights[i] ); |
Example 2.2 transforming elements using ‘transform each’
1 2 3 |
newHeights = transform each( {height},heights, height * 2.54 ); |
Example 3.1 the iteration index associated with a for loop
The iteration index is explicit in a for-loop:
1 2 3 4 5 |
for (i=1,i<=nitems(lstAges),i++, age = lstAges[i]; show(i,age) );<code> |
Example 3.2 using the index keyword
1 2 3 |
for each({index},lstAges, show(index) ); |
Notice that this is the identical syntax for the use of ‘for each’. The only difference is the name of the element is ‘index’. Index is a keyword that indicates you want the index of the item and not the item value. If you want both, see the next example.
Example 3.3 using element-index pairs
1 2 3 |
for each ({age,i}, lstAges, show(age,i) ); |
Example 4.1 working with associative arrays
For each can also be used to work with associative arrays:
1 2 3 4 5 6 7 |
lstAges = {12,13,14}; strAges = {"twelve","thirteen","fourteen"}; arr = Associative Array(lstAges,strAges); for each ( { {key,value} }, arr, show(key,value) ); |
1 2 3 4 5 6 |
key = 12 value = "twelve" key = 13 value = "thirteen" key = 14 value = "fourteen" |
Example 5.1 working with multiple lists
Sometimes we work with collections of lists to track multiple associated quantities. Here is an example:
1 2 3 4 5 6 7 8 9 10 11 |
lstParameters = {"Temperature","pH"}; lstLSL = {20,5.5}; lstTarget = {25,6.0}; lstUSL = {30,7.0}; for (i=1,i<=nitems(lstParameters),i++, parameter = lstParameters[i]; lsl = lstLSL[i]; target = lstTarget[i]; usl = lstUSL[i]; ); |
Example 5.2 for each item in multiple lists
1 2 3 |
foreach({parameter,lsl,target,usl},across(lstParameters,lstLSL,lstTarget,lslUSL), show({parameter,lsl,target,usl) ) |
Example 5.3 misasligned lists
When referencing items across lists the presumption is that the lists are of equal length. Problems occur if that is not the case:
1 2 3 4 5 6 7 8 |
lstParameters = {"Temperature","pH","Humidity"}; lstLSL = {20,5.5}; lstTarget = {25,6.0}; lstUSL = {30,7.0}; for each({ {parameter,lsl,usl} },across(lstParameters,lstLSL,lstUSL), show(parameter,lsl,usl) ) |
Output:
1 2 3 4 5 6 7 8 9 |
parameter = "Temperature" lsl = 20 usl = 30 parameter = "pH" lsl = 5.5 usl = 7 parameter = "Humidity" lsl = 20 usl = 30 |
Example 5.4 using the count option to resolve differences across containers
1 2 3 4 5 6 7 8 |
lstP = {"Temperature","pH","Humidity"}; lstLSL = {20,5.5}; lstTarget = {25,6.0}; lstUSL = {30,7.0}; for each({ {p,lsl,usl} },across(lstP,lstLSL,lstUSL,count("Shortest")), show(p,lsl,usl) ) |
Output:
1 2 3 4 5 6 |
p= "Temperature" lsl = 20 usl = 30 p= "pH" lsl = 5.5 usl = 7 |
Example 5.5 strict enforcement
1 2 3 4 5 6 7 8 9 10 11 12 |
try( for each({ {p,lsl,usl} }, across(lstP,lstLSL,lstUSL, count("Enforce Equal")), show(p,lsl,usl) ) , show("oops") ); |