Iterators in Details
reviewed: 22 February 2025
What are Iterators
Iterators are special CaseMaster objects that present some sort of collection that you can iterate over using the iterate - end-iterate construct.
The following shows a trivial example:
function doTest()
iterate iterator.ofNumber( 1, 10, 'i' )
response.write( concat( [i], ' x 7 = ', mul( [i], 7 ), '<br>' ) )
end-iterate
// Output
// 1 x 7 = 7
// 2 x 7 = 14
// 3 x 7 = 21
// 4 x 7 = 28
// 5 x 7 = 35
// 6 x 7 = 42
// 7 x 7 = 49
// 8 x 7 = 56
// 9 x 7 = 63
// 10 x 7 = 70
end-function
As you can see, iterator.ofNumber() in combination with iterate - end-iterate can be used to create the for() loop from other languages.
Another function in the iterator function handler is the iterator.ofDate() function to loop over dates:
function doTest()
iterate iterator.ofDate( today(), addDay( today(), 7 ) , 'date' )
response.write( concat( format( [date], 'dddd, dd/MM/yyyy' ), '<br>' ) )
end-iterate
// Output (when run on 22FEB25)
// Saturday, 22/02/2025
// Sunday, 23/02/2025
// Monday, 24/02/2025
// Tuesday, 25/02/2025
// Wednesday, 26/02/2025
// Thursday, 27/02/2025
// Friday, 28/02/2025
// Saturday, 01/03/2025
end-function
And iterator.ofToken() as a simple tokeniser:
function doTest()
iterate iterator.ofToken( 'Lorem ipsum dolor sit amet' , ' ', 'word' )
response.write( concat( [word], '<br>' ) )
end-iterate
// Output
// Lorem
// ipsum
// dolor
// sit
// amet
end-function
Other types of iterators will be explained in detail in other documents; the key ones are:
| Iterator | Usage | Covered where |
|---|---|---|
iterator.ofPB |
Iterate over entries in a property bag | Here |
iterator.ofAttribute |
Iterate over attributes of a BO descriptor | Here |
iterator.ofEntity |
Iterate over entities; used to define queries | Here |
iterator.ofBO |
Iterate over array of BO's; used when defining forms | Here |
Working with Iterators
Every iterator is an object and can thus be assigned to a variable or passed as a parameter.
Check the following example:
function doTest()
set( 'iterator', iterator.ofNumber( 1, 100, 'i' ) )
response.write( concat( page.call( './sumIterator', [iterator] ), '<br>' ) )
response.write( concat( page.call( './sumIterator', [iterator] ), '<br>' ) )
// Output
// 5050
// 0
end-function
function sumIterator( iterator )
iterate [iterator]
set( 'total', add( [total], [i] ) )
end-iterate
return [total]
end-function
The output of the 2nd call (0) is surprising. This is because, once you have iterated over an iterator, the cursor (an internal pointer keeping track of where we are in the iterator) is pointing to the end.
The solution is to reset the iterator as following improvement:
function sumIterator( iterator )
iterator.reset( [iterator] )
iterate [iterator]
set( 'total', add( [total], [i] ) )
end-iterate
return [total]
end-function
The iterator.count() function is used to count the number of items in an iterator:
function doTest()
set( 'iterator', iterator.ofNumber( 1, 100, 'i' ) )
response.write( concat( iterator.count( [iterator] ), '<br>' ) )
// Output
// 100
end-function
A special not on iterator.ofEntity() (see here) where iterator.ofCount() may have some unexpected side effects in special circumstances.
Another useful function is iterator.ofKey() which is especially useful when looping over entries in a property bag (see here).
<End of document>