Remote Synthesis
Search my blog:
Viewing By Entry / Main
Aug 28, 2007

Remove Empty Array Elements ColdFusion Function

Here's a simple but useful UDF for handling arrays in ColdFusion. I was working on something today where I would create an array that happened to have a number of undefined elements contained within. What I wanted was to have all the undefined elements removed. ColdFusion 8 did add the ArrayIsDefined() function, but I needed this to work on 7 as well, so I copied a bit from Ray Camden's ArrayDefined UDF. CFLib actually had an ArrayCompact UDF that has a similar goal, except that it will only work for arrays with simple values, while this will work for arrays with any type of value.

Now, before anyone criticizes the use of duplicate(), I will make it known that the original version of this function simply tried to modify the reference to the original array and returned nothing. Theoretically, this should have worked since arrays are passed by reference, but it didn't and I am not quite sure why. When I dumped the argument in the function itself after it ran, you would see the array was properly modified, but when I viewed the original it still showed the empty values. If anyone can explain this, I would love to hear it (p.s. for this, I was testing on 7).

<cffunction name="arrayRemoveEmpty" access="public" description="removes empty array elements" output="false" returntype="array">
<cfargument name="theArray" required="true" type="array" />
<cfset var i = 0 />
<cfset var newArray = duplicate(arguments.theArray) />
<cfloop from="#arrayLen(newArray)#" to="1" index="i" step="-1">
<cftry>
<cfset newArray[i] />
<cfcatch type="coldfusion.runtime.UndefinedElementException">
<cfset arrayDeleteAt(newArray,i) />
</cfcatch>
<cfcatch type="coldfusion.runtime.CfJspPage$ArrayBoundException">
<cfset arrayDeleteAt(newArray,i) />
</cfcatch>
</cftry>
</cfloop>
<cfreturn newArray />
</cffunction>

Comments
Brian Kotek
I have to ask the obvious question though: why not refactor the code building the array to not append empty elements? ;-)


Ben Nadel
How come you are catching specific error types? What kind of error would get thrown that would cause you NOT to want to delete the array item?


Brian Rinaldi
@Brian - Well, that is easier said than done. In this case, the elements in the array are navigation nodes that have a user controlled sort order. I place the elements in that position to easily maintain the order but the CMS system it relies on does not enforce that each position actually contain a node.

Anyway, that is one use for it but I think there are occasions when a function of this sort comes in handy.

@Ben - yeah, you are right. I thought of that since those specific messages are from Ray's original function but ended up just leaving it alone. It would be cleaner as just an &quot;any&quot; and really wouldn't have any impact on the function itself.


Brian Kotek
Ben, it's not a question of not wanting to delete the item if a unexpected type of error is thrown, but a question of wanting to know if an unexpected error is thrown. The defined exception types are expected. If something else goes wrong, it is not expected, and that means you probably want to know about it.


Brian Rinaldi
@Brian - I would normally agree with you, but we are talking about one line of code in the try block which I think fairly well negates the possibility of some other type of error. Still, since there is no negative impact to the more explicit version above I am inclined to just leave it alone and people can decide for themselves :)


Ben Nadel
@Brian,

I can understand the theory behind it, but given that the only CFTry statement is:

&lt;cfset newArray[i] /&gt;

Anything that would throw an error at this point, would probably ALSO throw an error in ArrayDeleteAt(). Sure, at that point, you are throwing two exceptions as opposed to one... but even that is theory - cause if the argument type is Array, then really the only legit exception would be an undefined element type (or course several Java types might evaluate to Array but not support Array functionality - but is that worth the explicit error type handling?)

... all to say, I think a straight-up CFCatch would suffice :)


Brian Kotek
A catch-all cfcatch would probably suffice, I agree. I was just pointing out the rationale of explicitly typing the caught exceptions. I'd probably err on the side of being overly specific. You just never know. Right about the time you start thinking &quot;there is no way this can ever happen&quot;, it does. ;-)


Ben Nadel
@Brian, I know what you're talking about; like, a few months ago I was all thinking &quot;There is no way ColdFusion can get better than this!&quot; and then BLAM! CF8 beta comes out :)


Mark Mandel
You know, it would probably have been faster to do a:

temp = newArray.get(i);
if(NOT isDefined(&quot;temp&quot;))
{
ArrayDeleteAt(newArray, i)
}

Because exception handling tends to be pretty sloooooow ;o)

I like the post tho' ;o)


Write your comment



(it will not be displayed)