Understanding Arrays and Structures
in ColdFusion
Part 2 of an Ongoing Saga:
(if you have not yet read part 1 of this tutorial, which deals with arrays,
please do so before proceeding)
Structures
As we learned earlier, an array is a useful mechanism for storing multiple
values in one variable.
Recall the array that showed the baseball players, along with the position they
play, and their age. The graphical representation looked something like:
arrPlayers(array)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
| 1 | John | Bob | Frank | Pete | Hank | Dave | Craig | Bill | Curly Joe |
| 2 | First Base | Second Base | Third Base | Shortstop | Left Field | Center Field | Right Field | Pitcher | Catcher |
| 3 | 30 | 22 | 28 | 26 | 31 | 33 | 24 | 22 | 25 |
So if we wanted to know who?s playing center
field, we would output #arrPlayers[6][1]#.
The problem with this is that looking at the variable #arrPlayers[6][1]#, it?s
really not at all intuitive what that variable represents.
#arrPlayers[3][3]#?what is it? Well, by looking at the grid above, we know it?s
28 (the age of Frank, the 3rd baseman)?but the above grid won?t always be
available.
If there were a more intuitive way of storing this data, wouldn?t that be great?
Enter structures. Structures (sometimes called ?associative arrays?) are similar
to arrays, in that they allow you to store multiple values in one single
variable. The difference is that instead of being based on mathematical
positions, a structure is based on key-value pairs.
For example:
<cfset stPlayer = structNew()>
This creates a new structure. Notice that unlike the arrayNew() function,
structNew() requires no arguments.
Recall that with arrays, we used an index to create a new value in the array (<cfset
arrPlayers[1][1]
= ?John? />)
With structures, we use a key. A key is nothing more than a name for a variable.
<cfset stPlayer.playerName =
?John? />
The key is ?playerName?. The value is ?John?. This illustrates the nature of
structures and the key-value pair relationship.
A <cfdump> of this simple structure shows the
following:
We can continue to add keys to this structure like so:
<cfset stPlayer.position =
?First Base? />
<cfset stPlayer .age = 30
/>
<cfset stPlayer.salary = 200,000
/>
<cfset stPlayer.bats = ?right?
/>
Refreshing our <cfdump> shows:
We now have all of the information about John in one variable. We know his name,
his age, his position, his salary, and that he bats right.
To output John?s name, we do: <cfoutput>#
stPlayer.playerName#</cfoutput>. VERY intuitive.
Much better than <cfoutput>#arrPlayers[1][1]#</cfoutput>.
Now when we view the code, we know precisely what our variables are doing.
<cfoutput># stPlayer.position#</cfoutput>
- what position does the player play?
<cfoutput># stPlayer.age#</cfoutput>
- what is the player?s age?
Now that you?ve seen a structure, let?s explain it a little bit better.
We created our structure with the structNew() function:
<cfset stPlayer = structNew()
/>
We then populated our structure by using dot-notation to specify a key within
the structure, and a value for that key:
<cfset stPlayer.playerName =
?John? />
We used that same dot notation to output a specific key?s value:
<cfoutput>#stPlayer.playerName#</cfoutput>
This dot-notation is the more common way to work with structures in ColdFusion.
You can, however, use array notation, since a structure is really nothing more
than an associative array.
<cfset stPlayer[?playerName?]
= ?John? />
<cfoutput>#stPlayer [?playerName?]#</cfoutput>
With array notation, we simply place the name of the key inside of brackets,
within quotes (because, in this case, the key is a literal value). NOTE that
with array notation, there is no dot.
While the dot-notation is the more common method, the array notation does have
some advantages. Specifically, you can ?cheat? with your key names.
By cheat, I mean that in dot notation, a key must be a syntactically valid
variable by ColdFusion standards (cannot start with a number, cannot contain
spaces or special characters). If you wanted the name of the key to be, for
example, Player Name, as opposed to playerName, you could NOT do:
<cfset stPlayer.Player Name =
?John? />
This will throw an error. Likewise, if you wanted to have a key called ?*? (and
don?t ask me why you?d want a key called *)?you could NOT do:
<cfset stPlayer.* =
?asterisk? />
You could, however, do:
<cfset stPlayer[?Player Name?]
= ?John? />
<cfset stPlayer[?*?]
= ?asterisk? />
While it?s unlikely that you?d need to resort to naming a key *, keep in mind
that array notation in structures is available, and allows you that flexibility.
NESTING STRUCTURES
It is also possible to nest structures if need be.
You might have a weather forecast for two different regions?let?s say Phoenix
and New York City. For each region, you have temperature, humidity, and wind.
All of that data can easily be stored in one (nested) structure.
<cfset stWeather = structNew()
/>
<cfset stWeather.Phoenix = structNew()
/>
<cfset stWeather.NYC = structNew()
/>
<cfset stWeather.Phoenix.temp = ?100F?
/>
<cfset stWeather.Phoenix.humidity = ?30%?
/>
<cfset stWeather.Phoenix.wind = ?2 MPH ENE?
/>
<cfset stWeather.NYC.temp = ?74F?
/>
<cfset stWeather.NYC.humidity = ?68%?
/>
<cfset stWeather.NYC.wind = ?12 MPH SE?
/>
Before showing a cfdump, let?s take a look at what we just did.
We create a structure named stWeather. This will be the ?outer? structure.
We then assigned two keys to this structure. The first key was ?Phoenix?, and
it?s value was a new (nested) structure. The second key was ?NYC?, and it?s
value was a new (nested) structure.
To access these nested structures, we simply continue with the dot-notation that
we?ve already learned. <cfoutput>#stWeather.NYC.temp#</cfoutput>
would display 74F, which is the value of the temperature in NYC. Even with
nested structures, note how intuitive the naming conventions make it.
For a little extra help with the visualization:
Obviously, we can easily store weather data for any number of additional cities
within this one variable. Likewise, we can store as many weather conditions as
are available. If we were given the barometer reading for NYC, we would simply
do:
<cfset stWeather.NYC.barometer =
38 />
Summary of Structures
To summarize structures, let?s go back to the baseball team examples. With
arrays, we could store information about players (including name, position,
salary, age, etc) in one variable. However, it was not intuitive as to where
these values were stored within the array. Could it be arrPlayers[2][6]?
arrPlayers[5][3]?
Structures help us to store these multiple values in a more intuitive manner. We
can even nest structures as deeply as we need to in order to fulfill our needs.
But structures have one shortcoming over arrays. Where we could store the
information for the entire baseball team in one array?we need a separate
structure for each player. We saw above that we can do <cfset
stPlayer.playerName = ?John?
/>. But what do we do when we want to add a second player?
See part 3 of this multi-part tutorial, which deals with, among other things,
arrays of structures.
In the meantime, make sure you understand what a structure is, how to create
one, and how to manipulate one. All of ColdFusion?s built-in structure functions
can be found in your online documentation, or at
http://livedocs.macromedia.com/coldfusion/6/CFML_Reference/functions-pt020.htm#1099964.
As always, if there are any questions or any areas that I can clarify for you,
please don?t hesitate to contact me directly, or via the
easycfm.com forums (preferably the
latter, so that others might benefit from the discussion).