I know that this is everyone’s favorite topic. It’s certainly the first chapter I look for when I get a new Learn <Insert Language Here> in 2 Minutes book.
Well, ok — maybe not. But the gruesome truth is that data structures are at the core of our very existence as developers. Whether you’re building a shell script to run on a *nix box or a full-fledged Windows desktop application, you’ll need data structures of some type.
Anyone who’s even briefly looked at ColdFusion has probably seen the most basic data structures, variables. Variables are generally set like this:
<cfset myVariable = \"This is my variable.\">
What many people have not experienced is the power of ColdFusion’s more advanced data structures. That’s okay, though, because in this article and the next, I’m going to introduce you to ColdFusion arrays and structures (or “structs”, as they’re called in CF).
We’ll begin by discussing how ColdFusion handles arrays. If you’ve developed software in any other language, you’re no doubt familiar with arrays and their various uses. If not, that’s okay — I’ll explain them here.
An array is simply a container that holds several variables with the same name. For example, let’s say you have a bowl of fruit and you want to create a variable for each fruit. You start with the apple:
<cfset fruit = \"apple\">
Now, you’ve got a fruit that is an apple. Great! You move on to the orange:
<cfset fruit = \"orange\">
Wait! Now you’ve got one fruit that is an orange, but no apples. This is because with the second
<cfset> you overwrote “apple” with “orange”. So, how can we describe all of our fruit, but still keep it classified in the same category: fruit? Well, we use an array for this:
<cfset fruit = ArrayNew(1)>
This creates an array named
fruit. It uses the function
ArrayNew, which takes a single parameter that must be an integer. For those of you who are familiar with other programming languages (like Visual Basic, for example), this parameter is deceptive. The parameter here is not defining how many elements your array will contain, but how many dimensions it will have. Before we talk any more about dimensions, let’s continue with a single dimension array. Now that we’ve created this one, we can add our fruit to it:
<cfset fruit = \"apple\"> <cfset fruit = \"orange\"> <cfset fruit = \"banana\">
Perfect! Now we’ve listed our entire bowl of fruit in a single variable name, so we can easily keep track of it. Let’s examine this a little further. First of all, in ColdFusion arrays are all dynamic. This means that ColdFusion does not require you to tell it how many elements your array will have in advance (other languages, like Java, require this). Second of all, the array indexing begins at 1, not 0. Languages like Java and C++ would begin the above array by setting
fruit = "apple".
Now, let’s talk about displaying an array. It’s really very simple. We’ll use a
<cfloop> and the
<cfloop from=\"1\" to=\"#ArrayLen(fruit)#\" index=\"i\"> <cfoutput>#i# = #fruit[i]#<br></cfoutput> </cfloop>
That’s not so hard, is it? Those three lines of code simply dump out the contents of the array, one element per line. Notice how you access each element, using the
i at the end of the variable name. What’s happening here is we’re starting our loop at 1, assigning that value to the variable i. We then display the position we’re currently at, and then access
fruit and display it. Next, it increments i to 2, displays the variables, and so on until i is equal to the length of the array.
For all you Java/C++ coders, we’re looping to the actual length of the array, not length minus one. In Java, this would throw an array out of bounds exception because indexing starts at 0 and goes to length minus one.
For those of you who are unfamiliar with arrays, each value stored in an array is called an element. Each element can be almost any type of data: a variable (integer, string, Boolean, etc.), a structure, or another array. When you have an array that has an element containing another array, then you have a multi-dimensional array. Just keep in mind that if you create a multidimensional array, such as a two dimensional array, the first dimension can only contain other arrays, not actual text data (i.e. strings or integers).
For example, let’s consider the fruit array we created above. Now, we want to keep track of the colors each fruit comes in. In order to do this, we’ll keep track of our colors in a multidimensional array. It’ll look like this:
<cfset colors = ArrayNew(2)> <cfset colors = \"green\"> <cfset colors = \"red\"> <cfset colors = \"yellow\"> <cfset colors = \"orange\"> <cfset colors = \"yellow\"> <cfset colors = \"green\">
This may look sort of complicated, but it really isn’t. All we’re doing is:
- defining a two dimensional array
- assigning values to the second dimension of each array
So, here’s a pop quiz: How many arrays do we have total? The answer: four. There is an array called colors that holds three other arrays, called
colors. We treat each of the last three arrays just as we did the fruit array, assigning values to the indexes. We can now display the colors for each fruit like this:
<cfloop from=\"1\" to=\"#ArrayLen(colors)#\" index=\"outer\"> <cfoutput><b>#outer# = #fruit[outer]#</b></cfoutput> <blockquote> <cfloop from=\"1\" to=\"#ArrayLen(colors[outer])#\" index=\"inner\"> <cfoutput>#inner# - #colors[outer][inner]#</cfoutput> </cfloop> </blockquote> </cfloop>
Here, what we’re doing is looping over the top level array (the first dimension) and displaying the fruit name (from the fruit array). Warning: it’s not a good idea to do this. Fruit may not have as many dimensions as colors does. This is for demonstrational purposes only.
Unless you’re creating a very simple e-fruit stand, the above examples don’t give you much to go on when you try to use arrays in real life. Here’s an example of how I’ve use arrays on some occasions.
Sometimes it can get pretty tedious trying to create dropdown boxes, especially for things like the months of the year or the days of the week. Here’s a simple way to eliminate the monotony of the task. First, we’ll create and populate our array.
<cfparam name="selectmonth" default="1"> <cfset months = ArrayNew(1)> <cfloop from="1" to="#DateFormat("12/31/2003", "mm")#" index="j"> <cfset months[j] = DateFormat("#j#/1/2003", "mmmm")> </cfloop>
The above code ensures that January will be the selected month. You could use a URL or Form variable for this, depending on your application. Then, we create a loop starting at 1 and going to 12. Notice, we use the last day of the year and Put it into
DateFormat() to get just the month number, or 12. We then assign each index from 1 to 12 with the name of the month. So, when we call DateFormat(“5/1/2003″, “mmmm”), it gets the date May 1st 2003 and then just pulls out the month name. Now, we’ll display our select box:
<select name="month"> <cfloop from="1" to="#ArrayLen(months)#" index="i"> <cfif selectmonth eq i> <option value="#i#" selected>#months[i]#</option> <cfelse> <option value="#i#">#months[i]#</option> </cfif> </cfloop> </select>
This loops from the beginning index of the array to the ending index to create the drop down box. It checks to see if the current month has been selected and marks it as such if necessary. It’s that easy! You can simply copy and paste the code to create the drop down box wherever you need it.
That’s it for our overview of using arrays of all sorts in ColdFusion. These handy data structures are essential in nearly every language you’ll ever encounter, so get acquainted with them very well. You never know when you might need them!
In our next article, we’ll be discussing ColdFusion structures (or structs) in depth, so don’t miss it!