Beginners Guide To CF: Complex Objects - Part 2

Posted By : todd sharp Posted At : September 1, 2006 6:00 AM Posted In: ColdFusion

0

As promised, here is part 2 to my introduction to complex objects. This post will focus on arrays and query objects. Arrays Important Links: Adobe Livedocs - Array Functions Adobe Livedocs - About Arrays Arrays can be a more difficult concept to grasp than structures or lists. They are a more complex 'container' than structs or lists, but as such they can be more powerful. Unlike structures, the index of an array is always numeric. Arrays can have multiple 'dimensions' which can lead to some confusion early on when trying to comprehend these objects. I'll borrow some text from the Livedocs which gives a good intro to Arrays:
The following terms will help you understand subsequent discussions of ColdFusion arrays: * Array dimension The relative complexity of the array structure. * Index The position of an element in a dimension, ordinarily surrounded by square brackets: my1Darray[1], my2Darray[1][1], my3Darray[1][1][1]. * Array element Data stored at an array index. The simplest array is a one-dimensional array, similar to a row in a table. A one-dimensional array has a name (the variable name) and a numerical index. The index number references a single entry, or cell, in the array, as the following figure shows:
To understand arrays, it is easier to look at some sample code. Here is a simple one dimensional array:
<!--- create an array - the ArrayNew function expects the
number of dimensions to be passed in as an argument --->

<cfset theArray = ArrayNew(1)>

<!--- reference elements in an array using bracket notation -
with a one dimensional array it looks like this--->

<cfset theArray[1] = "foo">
<cfset theArray[2] = "boo">

<!--- as always, take a dump --->

<cfdump var="#theArray#">
The visual representation that a dump gives us will help in understanding the concept of this 'container':

dumping a 1d array

As stated above, arrays will sometimes be multi-dimensional. Though this can seem intimidating, it really isn't that bad. A 2d array is nothing more than a 1d array that contains another 1d array within each element.
<!--- Create a 2d Array --->
<cfset theNextArray = ArrayNew(2)>
<!--- refernce the elements in a 2d array using
bracket notation as well - but this time use two brackets.
the left bracket will denote the left 'larger container'
and the right bracket will denote the inner 'sub-container' --->

<cfset theNextArray[1][1] = "bob">
<cfset theNextArray[1][2] = "smith">
<cfset theNextArray[2][1] = "joe">
<cfset theNextArray[2][2] = "boo">

<cfdump var="#theNextArray#">
Which looks like this -

dumping a 2d array

A 3d Array just builds on the previous concepts.
<!--- Create a 3d Array --->
<cfset yetAnotherArray = ArrayNew(3)>
<!--- reference the elements in a 2d array using
bracket notation as well - but this time use two brackets.
the left bracket will denote the left 'larger container'
and the right bracket will denote the inner 'sub-container' --->

<cfset yetAnotherArray[1][1][1] = "bob">
<cfset yetAnotherArray[1][1][2] = "smith">
<cfset yetAnotherArray[1][2][1] = "joe">
<cfset yetAnotherArray[1][2][2]= "boo">

<cfdump var="#yetAnotherArray#">
Which looks like this -

dumping a 3d array

This is a very simple overview of Arrays, but breaking it down to this level will hopefully give you a good understanding of the concepts surrounding the array 'container'. The more you work with them, the more comfortable you will become. Soon you will be iterating over an array dynamically to access the elements within them. Again, like the other 'containers', it's a good idea to read the documentation and become comfortable with the functions that are used to work with them. You will often see arrays containing structures (an arrayOfStructs), which really is not a difficult concept if you build on these concepts. A quick example:
<cfset s1 = structNew()>
<cfset s2 = structNew()>
<cfset a1 = arrayNew(1)>
<cfset s1.key1 = "value1">
<cfset s1.key2 = "value2">
<cfset s2.key1 = "value1">
<cfset s2.key2 = "value2">
<cfset a1[1] = s1>
<cfset a1[2] = s2>

<cfdump var="#a1#">

dumping an array of structs

To access the struct within each element:
<cfoutput>
The first element in the structure within the first element of the array is #a1[1].key1#
</cfoutput>
Queries Important Links: Adobe Livedocs - Query Functions I'm not sure if the query object fits the official definition of a 'complex object', however it is certainly a 'container' and should be understood as one. When I first started working with CF, for some reason I could not grasp the concept of a query being anything other than what was returned when you used the tag. However, many of the tags in CF return a query object (cfpop, cfdirectory just to name a few) and query objects can be created totally independent of the tag. It may help to think of the query object as a 'record set,' or a 'container' that looks exactly how you would expect data to look as it would in your database. That is, a single row of column headers followed by rows of data aligning with those headers. The query functions can be used to manipulate the query object (like adding a row or a column). Here's a quick example of creating a query object using query functions.
<!---
create a quick query object
--->

<cfset theQuery = QueryNew("userName, address, zipCode, phoneNumber")>
<!--- add a row --->
<cfset queryAddRow(theQuery, 1)>
<cfset querySetCell(theQuery, "userName", "bob smith", 1)>
<cfset querySetCell(theQuery, "address", "123 main st", 1)>
<cfset querySetCell(theQuery, "zipCode", "12345-1234", 1)>
<cfset querySetCell(theQuery, "phoneNumber", "123-456-7890", 1)>

<!--- if we had to break out the first section
of the zip code and create a new column for
some reason, here's how we'd do it --->


<!--- create a new one dimensional array for the new column --->
<cfset zipFirst = ArrayNew(1)>
<cfset queryAddColumn(theQuery, "zipWithoutLastFour", "integer", zipFirst)>

<cfloop from="1" to="#theQuery.recordCount#" index="i">
    <cfset theNewZip = listFirst(theQuery.zipCode, "-")>
    <cfset querySetCell(theQuery, "zipWithoutLastFour", theNewZip, i)>
</cfloop>

<cfdump var="#theQuery#">

dumping a query

That pretty much wraps up my overview of complex objects or as I like to call them 'containers.' I hope it has been helpful to someone out there. These are very critical building blocks. Many of the advanced techniques you may employ some day will no doubt demand an understanding of them. I was going to include an overview of XML objects in CF, but I think I'll hold off on that for now. Anyways, if you made it this far, thank you for reading! Other References ColdFusion Cookbook - Data Structures

Comments (0)