# Ask Ben: Looping From 'A' To 'Z' In ColdFusion

Posted December 19, 2006 at 2:52 PM by Ben Nadel

Tags: ColdFusion, Ask Ben

Is there an easy way to list from a to z in the alphabet?

There are few ways to loop over the letters A to Z using ColdFusion. Some are more complicated than others, but perhaps more useful. Let's start off by looking at traditional list loop. If you want, you could create a list of all letters between A and Z and loop over that:

• <!--- Loop over letters as a list. --->
• <cfloop
• index="strLetter"
• list="A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"
• delimiters=",">
•
• #strLetter#
•
• </cfloop>

This method is VERY simple and VERY straightforward. But, on the other hand, it is prone to error. Are you sure you wrote down all the letters? Did you miss any?

The next method would be to use an index loop based on the ASCII values of the letters from A to Z. The ASCII values are such that going from A to Z is an incrementing value list.

• <!--- Loop over ascii values. --->
• <cfloop
• index="intLetter"
• from="#Asc( 'A' )#"
• to="#Asc( 'Z' )#"
• step="1">
•
• <!--- Get character of the given ascii value. --->
• <cfset strLetter = Chr( intLetter ) />
•
• #strLetter#
•
• </cfloop>

This reduces room for error since you don't have to write out all of the letters. But on the flip side, you have go through the extra step of converting the ASCII value back to a character value, and it might not be as straight forward to someone reading the code.

Sometimes, what I like to do is load the letters right into a query. I find a query loop more intuitive some reason and it is much more reusable than a standard list.

• <!--- Create a query for the letters. --->
• <cfset qLetter = QueryNew( "" ) />
•
• <!--- Add the letters (one per record) to the query. --->
• <cfset QueryAddColumn(
• qLetter,
• "name",
• "CF_SQL_VARCHAR",
• ListToArray(
• "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"
• )
• ) />
•
• <!--- Loop over letter query. --->
• <cfloop query="qLetter">
•
• #qLetter.name#
•
• </cfloop>

This is clearly the most complicated of the three options, and certainly the least straight forward... but, I once you get the letters into the query, they are highly reusable. The physical CFLoop tag is much more simple, and it's more intuitive to scope the letter (which will reduce naming conflicts).

In practice, I tend to go with the ASC() to ASC() value index loop. It is a good combination of clear-to-read code and reduced risk of error.

### Looking For a New Job?

25% of job board revenue is donated to Kiva. Loans that change lives - Find out more »

### Reader Comments

Dec 19, 2006 at 5:39 PM // reply »
3 Comments

Thanks for the the answer. I like number two. I'm not even going to think about three right now. Basics now, advanced later.

Dec 19, 2006 at 6:37 PM // reply »
26 Comments

This is where CFSCRIPT is better than a tag. I've had this example in my Complete CFSCRIPT reference (http://www.houseoffusion.com/tutorial/cfscript/index8.cfm) for years and as you can see, the only time you have to do a transformation is on incrementation.

<CFSCRIPT>
For (i="M";i NEQ "P"; i=Chr(Asc(i)+1))
writeoutput(i&' ');
</CFSCRIPT>

Dec 19, 2006 at 7:53 PM // reply »
67 Comments

Firstly... Ben: your blog is usually quite interesting but today's tutorial is a bit torturous. Manually write out a list only to convert it into an array before converting it again into a query? Jesus. What a shambles. I realise you're just demonstrating... err... *something*... but god what a shite suggestion.

Michael. Hang your head in shame. I normally respect what comes out of your brain, but your example is on a par with Ben's (last) one. You're trying to be clever with your usage of for() expressions, I can see that; but have just come up with rubbish. It's both poor code, and poor logic behind the code in the first place.

You're claiming your own solution only needs "transformation" on increments. Yes. TWO transformations for each iteration. ASC() and CHR(). Applying some sense, one would evaluate the boundaries of the loop ONCE, and then iterate over them, rather than reevaluate them each time (despite knowing the answer of that reevaluation already).

For (i="M";i NEQ "P"; i=Chr(Asc(i)+1))

Get rid of all that sh*t.

iStart = asc('M');
iStop = asc('P');
for (i=iStart; i le iStop; i=i+1)//etc

For one, it's easier to read; for a second: it's better code; a trivial third is that it would be infinitesimally faster (which is not a sensible consideration).

--
Adam

Dec 19, 2006 at 8:06 PM // reply »
67 Comments

(and, much as it pains me to advocate CFML over CFscript... doing that in a <cfloop> would be better still, and gets us back to Ben's second suggestion).

--
Adam

Dec 19, 2006 at 8:50 PM // reply »
26 Comments

Which is why I gave the link so people can see the example in context. I'm not saying its what should be done, it's just what can be done in CFSCRIPT:
"8.6 The variable set and the end operation do not have to be numeric in nature. This example shows how to set the initial value to a character, increment the character and check it to see if the loop should end. It will output the letters M, N and O seperated by a space."

A CFLOOP can only compare numbers while a for loop can compare any ascii value. That's the bottom line of my original entry and of my post.

Dec 20, 2006 at 7:37 AM // reply »
11,694 Comments

@Michael,

I happen to like your solution, and unlike Adam, I do find it readable. It emphasizes the FROM and TO parts of the loop. Frankly, the incremental portion doesn't even need to be as readable if you understand what the loop is doing overall.

And, from what I can see, Adam's loop example is doing pretty much the same as one of my examples, just breaking it out into ??more?? readable steps.

@Adam,

Admittedly, I wouldn't go for option 3 most of the time. But, there are times where having the letters in a query is awesome. Think about taking a query returned from the database and grouping it based on letters? (think last name). Having the whole alphabet in a query would allow you do an easy GROUP BY and find letters where there were no matching records.

On top of that, the query is the most easily reusable. You could loop over it at the top of the page (outputting a list of letters as links or anchors) and then do the same thing on the bottom of the page, and use it to join to another query. It's more complex upfront, but it becomes much more flexible and reusable in the long run.

The best solution is going to depend on the situation.

Dec 20, 2006 at 11:08 AM // reply »
21 Comments

Hi All,

For all that previous ways, the best way I like to use is this:

The best solution is going to depend on the situation.

Ameen

Aug 20, 2008 at 2:50 PM // reply »
3 Comments

I was trying to find an elegant way to create an A-Z list, and this blog entry came up in a google search.

I ended up using the third solution so that I could loop over the array and compare to records in my database that had data under them, and then used the results to create named anchors for my page.

Thanks Ben!

Aug 20, 2008 at 3:14 PM // reply »
11,694 Comments

@Karen,

Glad to help :)

May 11, 2010 at 1:45 AM // reply »
20 Comments

Hi .. I like this Methodology Good!

* <!--- Loop over ascii values. --->
* <cfloop
* index="intLetter"
* from="#Asc( 'A' )#"
* to="#Asc( 'Z' )#"
* step="1">
*
* <!--- Get character of the given ascii value. --->
* <cfset strLetter = Chr( intLetter ) />
*
* #strLetter#
*
* </cfloop>

Little Tweaks to set in a select Box like this

<select name="class" id="class" tabindex="1">
<cfloop index="intLetter" from="#Asc('A')#" to="#Asc('F')#" step="1">
<!--- Get character of the given ascii value. --->
<cfset strLetter = Chr( intLetter ) />
<cfoutput>
<option value="#strLetter#">#strLetter#</option>
</cfoutput>
</cfloop>
</select>

Cheers

May 11, 2010 at 7:49 AM // reply »
11,694 Comments

@Gavy,

Heck yeah - CFLoop is awesome.

Oct 14, 2010 at 11:56 AM // reply »
3 Comments

One thing to mention regarding the difference between method 1 and 2.

Method 2 is definitely more straight-forward, but it assumes a Latin alphabet. It will produce problems with any modified Latin alphabet such as French, Spanish and in fact most European languages other than English.

So for those who aim to support multiple languages, method 1 is probably better for those purposes. Of course, if the only target language is English, there's nothing wrong with the 2nd one.

Just throwing it in there! Thanks, Mr. Nadel!

Oct 24, 2010 at 1:44 PM // reply »
11,694 Comments

@Helgi,

That's a good point. I'm not too familiar with how people go about dealing with internationalization (i18n). I think a lot of times, people use "resource packs" to abstract the language being used. Perhaps this kind of a list could be moved to a resource pack.

Feb 22, 2011 at 2:14 PM // reply »
10 Comments

I usually opt for a cfscript and looping solution. This time, since I'll be using this snippet of code in several places throughout my "lightweight" site, I decided to create a hard coded list and put it in the application scope.

Unlike Ben, I feel really confident in my ability to create a comprehensive and accurate list of letters of the alphabet. (Yeah, I'm just teasing you, Ben!)

I can put initalize this in the application.cfc in the onApplicationStart method. I can then forget about it until I need to use a list of letters.

1) It's fast enough.
2) It's not a memory hog.
3) It's reusable.
4) It's easy to read.
5) It's easy to update (if and when we add to or remove from letters of the alphabet).

<cfscript>
APPLICATION.GeneralData = structNew();
APPLICATION.GeneralData.aThroughZ = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
</cfscript>

Thanks for the conversation and assistance, Ben (et al).

Dec 24, 2013 at 11:04 PM // reply »
2 Comments

<cfloop from='65' to='90' index=i><cfoutput>#chr(i)#</cfoutput></cfloop>

is short and efficient

### Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

 Author Name: Author Email: Author Website: Comment: Supported HTML tags for formatting: bold   italic   code Remember my information Subscribe to comments Send me a copy of this comment
InVision App - Prototyping Made Beautiful With Prototyping Tools Recent Blog Comments
Mar 11, 2014 at 2:00 AM
ColdFusion, jQuery, And "AJAX" File Upload Demo
hey Ben Nadel thanks for this tutorial. i have downloaded your code also but no luck.. i am new to this so , can you explain me some thing about this cf prefix ? ... read »
Mar 10, 2014 at 8:24 PM
Nested Views, Routing, And Deep Linking With AngularJS
@Steven, the action property is not something from AngularJS but rather part of the concept that Ben is describing in his blogpost here. it is a custom added property, which is read by the requestCo ... read »
Mar 10, 2014 at 2:03 PM
Nested Views, Routing, And Deep Linking With AngularJS
Where is the angular documentation for 'action:' it is not here: http://docs.angularjs.org/api/ngRoute/provider/ \$routeProvider Thanks. ... read »
Mar 10, 2014 at 12:06 PM
Using Track-By With ngRepeat In AngularJS 1.2
I was hoping that this will work with pagination using ng-repeat. My use case scenario is that I have an images object. images[0] = [im1,im2,im3] // First Page images[1] = [im4, im5, im6] // Second ... read »
Mar 9, 2014 at 6:11 PM
For Better Security Use HtmlEditFormat() In Conjunction With JSStringFormat() In ColdFusion
It looks like htmleditformat() will be deprecated in CF 11 https://wikidocs.adobe.com/wiki/display/coldfusionen/New +in+ColdFusion ... read »
Mar 9, 2014 at 10:55 AM
\$.stop() vs. \$.finish() In jQuery Animations
Nice feature! Thanks for sharing. :) Good for when you are making a 100% AJAX controlled site. ... read »
Mar 9, 2014 at 12:26 AM
Experimenting With Multiple Class Inheritance In Javascript
@bigboomshakala, Hi, I am want present so solution for multiple prototypical inheritance, but some restrictions. Please follow the link: http://arto8.site11.com/ArtoJS/multi-inheritance-prototype.ph ... read »
Mar 8, 2014 at 5:21 PM
Thoroughly Document Your Use Of ColdFusion's CFHTMLHead Tag
hi Ben, how can we mention our own custom tags instead of using HTML tags in coldfusion? kindly revert with an example. ... read »