Fun with <cfloop collection="array">

December 2, 2010 · By Gert Franz · 2 Comments

I am sure many of you used the following (or a similar) notation in order to loop over an array:

<cfset aArray = ["January","February","March","April","May","June","July","August","September","October","November","December"]>

<cfloop from="1" to="#arrayLen(aArray)#" index="i">
   <cfoutput>#i#: #aArray[i]#<br></cfoutput>
</cfloop>

This works very well even though one has always the necessity of getting the length of an array. So why not (I am assuming the array is set in a line before): <cfloop array="#aArray#" index="i">
   <cfoutput>#i#: #aArray[i]#<br></cfoutput>
</cfloop>

Well that would break since i already contains the value of the array so it should have to be done like this:

<cfset iCnt = 0>
<cfloop array="#aArray#" index="i">
   <cfoutput>#++iCnt#: #i#<br></cfoutput>
</cfloop>

But this is ugly right? Or what happens if I even have the following array:

<cfset aArray = []>
<cfset aArray[2] = "February">
<cfset aArray[4] = "April">
<cfset aArray[6] = "June">
<cfset aArray[8] = "August">
<cfset aArray[10] = "October">
<cfset aArray[12] = "December">
Then the second solution wouldn't work since the position of the element is unknown. Only the first one would work with a little conditioning:

<cfloop from="1" to="#arrayLen(aArray)#" index="i">
   <cfif arrayIndexExists(aArray, i)>
      <cfoutput>#i#: #aArray[i]#<br></cfoutput>
   </cfif>
</cfloop>

In other engines I guess you have to use <cfif isDefined(aArray[i])> if possible. But why not use a very nice way of looping over arrays by using the collection loop (This only works on Railo):

<cfset aArray = ["January","February","March","April","May","June","July","August","September","October","November","December"]>

<cfloop collection="#aArray#" item="i">
   <cfoutput>#i#: #aArray[i]#<br></cfoutput>
</cfloop>
<br>
<cfset aArray = []>
<cfset aArray[2] = "February">
<cfset aArray[4] = "April">
<cfset aArray[6] = "June">
<cfset aArray[8] = "August">
<cfset aArray[10] = "October">
<cfset aArray[12] = "December">

<cfloop collection="#aArray#" item="i">
   <cfoutput>#i#: #aArray[i]#<br></cfoutput>
</cfloop>

The generated output is:
1: January
2: February
3: March
4: April
5: May
6: June
7: July
8: August
9: September
10: October
11: November
12: December

2: February
4: April
6: June
8: August
10: October
12: December

So using the collection notation in really helps you speed up coding and even respects empty indexes.

Tags: Features · HowTo · Railo 3.0 · Railo 3.1 · Railo 3.2 · Tips

2 responses so far ↓

  • 1 Paul Klinkenberg // Dec 3, 2010 at 10:20 AM

    This is a great tip! Finally a simple way of looping through arrays :-))
  • 2 Andrew Clarke // Dec 15, 2010 at 3:11 PM

    These are great tips. Additionally, this will work for looping through lists, i.e.:

    <cfloop index="i_month" list="January,February,March">
       #i_month#
    </cfloop>

    What about cfscript, though? For instance, I'd really like to be able to do this:

    // Loop through a list
    for (i_month in "January,February,March") writeOutput(i_month);

    or this:

    // Loop through an array
    for (i_month in ["January","February","March"]) writeOutput(i_month);

    I know this has come up before, but I'd really like to not have to choose between staying in cfscript and writing contorted for loops, or dropping out of cfscript to use an elegant cfloop.

Leave a Comment

Leave this field empty: