In ColdFusion, an iterator is an object, which defines a sequence and a return value upon its termination. The iterator protocol defines a standard way to produce a sequence of values (either finite or infinite), and potentially a return value when all values have been generated.
ColdFusion Components can be made iterable and UDF's are used as iterators.
How to make a cfc iterable ?
If the CFC implements __iter__ function with no arguments it will be called to get the iterator instance. The iterable function can return array, String, query, function (like below) or a cfc which has a function named __next()__.
CFC as an iterator
1 2 3 4 5 6 | // Iterator.cfc component { public any function __next__(previous, count){ // Follows Iteration Protocol as UDF return {value: count+1, done: count > 11}; } } |
1 2 3 4 5 6 | # cfcAsIterator.cfc component { public any function __iter__() { return new Iterator(); } } |
1 2 3 4 5 6 7 8 9 | // stringAsIterator.cfc component{ public any function __iter__() { str1= "ColdFusion 2021" ; str2= "Project Stratus" ; return [...str1,...str2]; } } |
1 2 3 4 5 6 7 8 9 10 | // udfAsIterator.cfc //Example using UDF as Iterator and CFC is the Iterable component { public any function __iter__() { var startFrom = 100; return function(previous, index){//Iterator UDF return { "value" : startFrom + index, "done" : index > 9}; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // udfAsIterator.cfm < cfscript > /* Plain UDF/Closure/Lambda as Iterator Invoking iterators using forin loop */ iterator = (previous, count) =>{ return { "value" : count + 2, "done" : count > 9}; }; writeoutput ( "----------- UDF/Closure/Lambda as Iterator -------------<hr>" ) for(i in iterator) { writeoutput (i & " " & "" ); } udfIteratorOBj = new udfAsIterator(); stringIteratorObj= new stringAsIterator(); cfcIteratorObj = new cfcAsIterator(); writeoutput ( "----------- UDF as Iterator -------------<hr>" ) for(i in udfIteratorOBj) { writeoutput ( SerializeJson (i) & "" ); } writeoutput ( "----------- String as Iterator -------------<hr>" ) for(i in stringIteratorObj) { writeoutput ( SerializeJson (i) & "" ); } writeoutput ( "----------- CFC as Iterator -------------<hr>" ) for(i in cfcIteratorObj ) { writeoutput ( SerializeJson (i) & "" ); } </ cfscript > |
Output
----------- UDF/Closure/Lambda as Iterator -------------
3 4 5 6 7 8 9 10 11 12
----------- UDF as Iterator -------------
101.0102.0103.0104.0105.0106.0107.0108.0109.0110.0
----------- String as Iterator -------------
"C""o""l""d""F""u""s""i""o""n"" ""2""0""2""1""P""r""o""j""e""c""t"" ""S""t""r""a""t""u""s"
----------- CFC as Iterator -------------
2.03.04.05.06.07.08.09.010.011.012.013.0
Array as iterator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // arrayAsIteratorwithSpread.cfc component{ public any function __iter__() { arr1=[1,2,3] arr2=[4,5,6] return [...arr1,...arr2]; } function demofunc(){ return "demostring!" } } |
1 2 3 4 5 6 7 8 9 10 | // arrayAsIterator.cfm < cfscript > arrayIteratorObj1= new arrayAsIteratorwithSpread(); writeoutput ( "----------- Array as Iterator 1-------------<hr>" ) for(i in arrayIteratorObj1 ) { writeoutput (i & "" ); } </ cfscript > |