# <cfloop>

Looping is a very powerful programming technique that lets you repeat a set of instructions or
display output repeatedly until one or more conditions are met.

cfloop supports five types of loops.

This tag **must** have a body.
This tag is also supported within [<cfscript>](script.md)

```
<cfloop
    index=string
    from=number
    to=number
    step=number
    condition=string
    query=object
    startRow=number
    endRow=number
    maxRows=number
    list=string
    array=array
    delimiters=string
    collection=any
    struct=struct
    item=string
    file=string
    characters=number
    startLine=number
    endLine=number
    charset=string
    group=string
    groupCaseSensitive=boolean
    label=string
    times=numeric
><!--- body ---></cfloop>
```

# Attributes

| Attribute | Type | Required | Description | Default |
|-----------|------|----------|-------------|---------|
| index | string | No | Index value. Lucee sets it to from value and increments or decrements by step value, until it equals to value. When looping over a Struct/Collection: - When the Item attribute is also defined, the variable assigned to the Index attribute will contain the value of the Struct's Key/Value pair (otherwise, it will always contain the Key value) - When only the Index or Item attribute is defined, the variable will always contain the Key value. *Alias: key* |  |
| from | number | No | Beginning value of index. |  |
| to | number | No | Ending value of index. |  |
| step | number | No | Step by which to increment or decrement the index value. |  |
| condition | string | No | Condition that controls the loop. |  |
| query | object | No | Query that controls the loop. This can be a variable name or the query itself. |  |
| startRow | number | No | First row of query that is included in the loop. |  |
| endRow | number | No | Last row of query that is included in the loop. You cannot use this attribute together with the attribute maxRows. |  |
| maxRows | number | No | Specifies the maximum number of rows to display in the output section. You cannot use this attribute together with the attribute endrow. |  |
| list | string | No | A list, variable, or file name; contains a list. Used with the index attribute. |  |
| array | array | No | An array. |  |
| delimiters | string | No | Character(s) that separates items in list |  |
| collection | any | No | Collection to loop over. Used with the item attribute. |  |
| struct | struct | No | struct to loop over |  |
| item | string | No | Key for the collection *Alias: value* |  |
| file | string | No | file path |  |
| characters | number | No | The number of characters to read during each iteration of the loop from the file specified in the file attribute. If the value of the characters attribute is more than the number of characters in the file, Lucee uses the number of characters in the file. |  |
| startLine | number | No | start line |  |
| endLine | number | No | end line |  |
| charset | string | No | charset for read the file |  |
| group | string | No | Specifies the query column to use when you group sets of records together to send as an e-mail message. For example, if you send a set of billing statements to customers, you might group on "Customer_ID." The group attribute, which is case sensitive, eliminates adjacent duplicates when the data is sorted by the specified field. See the Usage section for exceptions. |  |
| groupCaseSensitive | boolean | No | Boolean indicating whether to group with regard to case or not. The default value is NO; case is considered while grouping. If the query attribute specifies a query object that was generated by a case-insensitive SQL query, set the groupCaseSensitive attribute to NO to keep the recordset intact. |  |
| label | string | No | used to address this loop from a "break" or "continue" statement (instead of the nearest one). |  |
| times | numeric | No | used for a simple loop that is looping n times |  |

# Examples

### Index & Conditional loop

```cfml
<cfloop index = "LoopCount" from = "1" to = "5">
	The loop index is <cfoutput>#LoopCount#</cfoutput><br>
</cfloop>
<br><u>Conditional loop</u><br>
<cfset CountVar = 1>
<cfloop condition = "CountVar LESS THAN OR EQUAL TO 5">
	<cfset CountVar = CountVar + 1>
	CountVar is <cfoutput>#CountVar#</cfoutput><br>
</cfloop>
```

### List loop

```cfml
<cfset listEle = "lucee,test,case">
<br><u>Simple list loop</u><br>
<cfloop list="#listEle#" index="res">
	<cfoutput>#res#</cfoutput><br>
</cfloop>
<br><u>List loop</u><br>
<cfset listDeliEle = "I;Love;Lucee">

<cfloop list="#listDeliEle#" index="element" delimiters=";">
	<cfoutput>#element#</cfoutput><br>
</cfloop>
<br><u>deli loop with index</u><br>

<cfloop index="a" from="1" to="#listlen(listEle)#">
	<cfoutput>#listgetat(listEle,a)#</cfoutput><br>
</cfloop>
<br><u>Condition with list</u><br>
<cfset cV = 1>
<cfloop condition="cv lte #listlen(listele)#">
	<cfoutput>#listgetat(listEle,cV)#</cfoutput><br>
	<cfset cV = cV+1>
</cfloop>
```

### Array loop & Struct loop

```cfml
<cfoutput>
	<cfset arr = ["I","Love","Lucee"]>
	<br><u>Array using index loop</u><br>
	<cfloop array="#arr#" index="arr">
		#arr#<br>
	</cfloop>

	<cfset Departments = {"Save ":"Water ", "Plant ":"gren ", "Protect ":"Earth "}>
    <br><u>Struct loop</u><br>
	<cfloop collection="#Departments#" item = "person">
			#person#
			#StructFind(Departments, person)#<br>
	</cfloop>
</cfoutput>
```

### Query loop

```cfml
<cfset qry = ExtensionList()>
<cfloop query="#qry#">
    <cfoutput>#qry.currentrow#</cfoutput>
</cfloop>
<br>
<cfscript>
  loop query="#qry#"{
    echo( qry.currentrow & " " );
    if (qry.currentrow eq 10)
        break;
    if (qry.currentrow mod 2 eq 1)
        continue;
    echo( "... " );
  }
</cfscript>
```








# Categories

[Core CFML Language](../../categories/core.md)

# See Also

[Loop Labels](../../recipes/loop-labels.md), [Looping Through Files](../../recipes/loop-through-files.md), [Loop - times](../../guides/lucee-5/times.md), [<cfbreak>](break.md), [<cfcontinue>](continue.md), [<cfwhile>](while.md)