2 dimensional arrays
October 01, 2008
If you are new to programming, then you might not have discovered 2 dimensional arrays yet. They are a powerful tool and well worth learning. This post is for you!
Ever wondered how to store a table of data in a ColdFusion variable? Well 2-dimensional arrays could provide the answer. For instance how would you put this information into a useable format?
| Skywalker | Luke | Mark Hamill |
| Solo | Han | Harrison Ford |
| Kenobi | Obi-Wan | Sir Alec Guinness |
OK, let's look at a simple one dimensional array to get started.
<cfset aCharacters = ArrayNew(1) /> <cfset aCharacters[1] = "Skywalker" /> <cfset aCharacters[2] = "Solo" /> <cfset aCharacters[3] = "Kenobi" />
You can also write it like this if you prefer:
<cfset aCharacters = ArrayNew(1) /> <cfset ArrayAppend( aCharacters, "Skywalker" ) /> <cfset ArrayAppend( aCharacters, "Solo" ) /> <cfset ArrayAppend( aCharacters, "Kenobi" ) />
Looping through the information is easy.
<cfoutput> <cfloop from="1" to="#ArrayLen( aCharacters )#" index="row"> Row #row#: #aCharacters[row][1]#<br /> </cfloop> </cfoutput>
So how do we add the other columns? The example above can be thought of as one column with 3 rows in a spreadsheet (it's basically just a list), so we just need to add some more columns. This is now a 2 dimensional array as we know have rows and more than 1 column.
<!--- define a 2-dimensional array ---> <cfset aCharacters = ArrayNew(2) /> <cfset aCharacters[1][1] = "Skywalker" /> <cfset aCharacters[1][2] = "Luke" /> <cfset aCharacters[1][3] = "Mark Hamill" /> <cfset aCharacters[2][1] = "Solo" /> <cfset aCharacters[2][2] = "Hans" /> <cfset aCharacters[2][3] = "Harrison Ford" /> <cfset aCharacters[3][1] = "Kenobi" /> <cfset aCharacters[3][2] = "Obi-Wan" /> <cfset aCharacters[3][3] = "Sir Alec Guinness" /> <cfoutput> <cfloop from="1" to="#ArrayLen( aCharacters )#" index="row"> Row #row#: #aCharacters[row][1]#, #aCharacters[row][2]#, #aCharacters[row][3]#<br /> </cfloop> </cfoutput>
Pretty simple, but not very easy to read. We can make it easier to read by setting up some variables for our column headers.
<!--- define a 2-dimensional array ---> <cfset aCharacters = ArrayNew(2) /> <!--- define constants for column names ---> <cfset firstname = 1 /> <cfset lastname = 2 /> <cfset actor = 3 /> <cfset aCharacters[1][lastname] = "Skywalker" /> <cfset aCharacters[1][firstname] = "Luke" /> <cfset aCharacters[1][actor] = "Mark Hamill" /> <cfset aCharacters[2][lastname] = "Solo" /> <cfset aCharacters[2][firstname] = "Hans" /> <cfset aCharacters[2][actor] = "Harrison Ford" /> <cfset aCharacters[3][lastname] = "Kenobi" /> <cfset aCharacters[3][firstname] = "Obi-Wan" /> <cfset aCharacters[3][actor] = "Sir Alec Guinness" /> <cfoutput> <cfloop from="1" to="#ArrayLen( aCharacters )#" index="row"> Row #row#: #aCharacters[row][lastname]#, #aCharacters[row][firstname]#, #aCharacters[row][actor]#<br /> </cfloop> </cfoutput>
2 Dimensional arrays are a common practice in all languages, however with ColdFusion you also have alternative ways to store this information. The first is to create a structure and store that in an array, the second is to use a ColdFusion Query.
The structure approach can be done like this:
<!--- define a 1-dimensional array ---> <cfset aCharacters = ArrayNew(1) /> <!--- create a structure to store inside our array ---> <cfset stCharacter = StructNew() /> <!--- assign values to our structure ---> <cfset stCharacter.lastname = "Skywalker" /> <cfset stCharacter.firstname = "Luke" /> <cfset stCharacter.actor = "Mark Hamill" /> <!--- store structure in our array ---> <cfset ArrayAppend( aCharacters, StructCopy( stCharacter ) ) /> <cfset stCharacter.lastname = "Solo" /> <cfset stCharacter.firstname = "Han" /> <cfset stCharacter.actor = "Harrison Ford" /> <cfset ArrayAppend( aCharacters, StructCopy( stCharacter ) /> <cfset stCharacter.lastname = "Kenobi" /> <cfset stCharacter.firstname = "Obi-Wan" /> <cfset stCharacter.actor = "Sir Alec Guinness" /> <cfset ArrayAppend( aCharacters, StructCopy( stCharacter ) ) /> <cfoutput> <cfloop from="1" to="#ArrayLen( aCharacters )#" index="row"> Row #row#: #aCharacters[row].lastname#, #aCharacters[row].firstname#, #aCharacters[row].actor#<br /> </cfloop> </cfoutput>
You may be wondering what the StructCopy() function does. Well, if we didn't, then when we add the character structure to our array, we are only actually assigning a reference to the structure, not that actual values. This means that you when you loop through the array, all the values will be the same. By using StructCopy(), we are assigning an independant clone of the structure and values which will not be affected by subsequent changes to our struct.
Here's how you would do it using a ColdFusion query object:
<cfset qCharacters = QueryNew( "lastname,firstname,actor" ) /> <cfset QueryAddRow( qCharacters ) /> <cfset QuerySetCell( qCharacters, "lastname", "Skywalker" ) /> <cfset QuerySetCell( qCharacters, "firstname", "Luke" ) /> <cfset QuerySetCell( qCharacters, "firstname", "Mark Hamill" ) /> <cfset QueryAddRow( qCharacters ) /> <cfset QuerySetCell( qCharacters, "lastname", "Solo" ) /> <cfset QuerySetCell( qCharacters, "firstname", "Hans" ) /> <cfset QuerySetCell( qCharacters, "firstname", "Harrison Ford" ) /> <cfset QueryAddRow( qCharacters ) /> <cfset QuerySetCell( qCharacters, "lastname", "Kenobi" ) /> <cfset QuerySetCell( qCharacters, "firstname", "Obi-Wan" ) /> <cfset QuerySetCell( qCharacters, "firstname", "Sir Alec Guinness" ) /> <cfoutput> <cfloop query="qCharacters"> Row #qCharacters.CurrentRow#: #qCharacters.lastname#, #qCharacters.firstname#, #qCharacters.actor#<br /> </cfloop> </cfoutput>
So take your pick. I hope this explains 2 dimensional arrays and how to use them.
- Posted in:
- ColdFusion
4 comments
Leave a comment
If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

If I know or suspect that I'm going to have to search through the data set, I go with the query object option so I can use SQL to retrieve the record or records I want.
Comment by Brian Swartzfager – October 01, 2008
Comment by John Whish – October 02, 2008
<pre>
<cfscript>
aCharacter = [
["Skywalker","Luke","Mark Hamill"],
["Solo","Han","Harrison Ford"],
["Kenobi","Obi-Wan","Sir Alec Guinness"]
];
</cfscript>
</pre>
or
<pre>
<cfscript>
aCharacter = [
{lastname="Skywalker",firstname="Luke",actor="Mark Hamill"},
{lastname="Solo",firstname="Han",actor="Harrison Ford"},
{lastname="Kenobi",firstname="Obi-Wan",actor="Sir Alec Guinness"}
];
</cfscript>
</pre>
Take a look at Ben Nadel's blog
Comment by Stephen Moretti – October 02, 2008
<cfloop array="#aCharacters#" index="row">
For any readers that are interested, I did a quick post a while back on the shorthand style that CF8 developers can use:
www.aliaspooryorik.com/blog/index.cfm/e/posts.details/post/coldfusion-8-shorthand-8
Comment by John Whish – October 02, 2008