Appending One Array To Another With ArrayAppendAll() In ColdFusion

Posted November 19, 2010 at 11:25 AM by Ben Nadel

Tags: ColdFusion

This is just a super quick post about merging or concatenating two arrays in ColdFusion. Currently, the only way to natively join two arrays in ColdFusion is to use arrayAppend(), pushing one value at a time from the incoming array onto the target array. You can use the undocumented Collection method - array.addAll() - which I've done a number of times; but, if you want to keep things completely ColdFusion-friendly, you have to use a ColdFusion user defined function like arrayAppendAll().

To see this UDF in action, we'll create two arrays and then append one to the other:

  • <cffunction
  • name="arrayAppendAll"
  • access="public"
  • returntype="array"
  • output="false"
  • hint="I append (concat) the entire incoming array to the target array.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="targetArray"
  • type="array"
  • required="true"
  • hint="I am the array being augmented"
  • />
  •  
  • <cfargument
  • name="incomingArray"
  • type="array"
  • required="true"
  • hint="I am the array being added to the target array."
  • />
  •  
  • <!--- Define the local scope. --->
  • <cfset var local = {} />
  •  
  • <!---
  • Loop over the incoming array and add each value to the
  • target array. If we wanted to get *naughty*, we could use
  • the Collection-based interface of the array:
  •  
  • array.addAll( array )
  •  
  • However, to keep things ColdFusion-friendly, we'll perform
  • the array augmentation manually.
  • --->
  • <cfloop
  • index="local.incomingValue"
  • array="#arguments.incomingArray#">
  •  
  • <!--- Append the incoming value. --->
  • <cfset arrayAppend(
  • arguments.targetArray,
  • local.incomingValue
  • ) />
  •  
  • </cfloop>
  •  
  • <!---
  • Since arrays are passed by VALUE in ColdFusion, we have to
  • return the resultant array.
  • --->
  • <cfreturn arguments.targetArray />
  • </cffunction>
  •  
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  •  
  • <!--- Create an array of women. --->
  • <cfset women = [ "Sarah", "Tricia", "Joanna" ] />
  •  
  • <!---
  • Create an incoming array of women that we want to add to
  • the first one.
  • --->
  • <cfset incomingWomen = [ "Katie", "Jill", "Erica" ] />
  •  
  • <!---
  • Add one array to the other.
  •  
  • NOTE: Since ColdFusion arrays are passed by VALUE, we have to
  • overwrite the "women" variable with the resultant array.
  • --->
  • <cfset women = arrayAppendAll( women, incomingWomen ) />
  •  
  • <!--- Output the list of women. --->
  • <cfoutput>
  •  
  • Women: #arrayToList( women, " - " )#
  •  
  • </cfoutput>

As you can see, we're still looping over the incoming array, copying over its values one index at a time; but, since this is now encapsulated in a UDF, it's much easier to do. Running the above code gives us the following output:

Women: Sarah - Tricia - Joanna - Katie - Jill - Erica

As you can see, we were able to concatenate the two arrays.

Since arrays are passed by value in ColdFusion, our UDF cannot work directly on the original array. Instead, arrayAppendAll() has to work on its own copy which it then returns as a result of the function execution. It is then up to the calling context to store that resultant array back into the most appropriate variable.

I'd really like an arrayAppendAll() function (or something similar) to be added to the ColdFusion core language. I find this kind of situation comes up a lot. And, since it's a method of the underlying Collection interface, I have to believe that it would be really easy for the ColdFusion engineers to implement.




Reader Comments

Nov 19, 2010 at 12:00 PM // reply »
140 Comments

Au contraire sir, if you simply write your udf to accept strings instead of variables you'll be able to inject the resulting array into the calling variables scope and get the result you're looking for.


Nov 19, 2010 at 4:27 PM // reply »
10 Comments

The java way is simpler, and faster.


Nov 19, 2010 at 4:37 PM // reply »
10,743 Comments

@David,

That would only work IF you knew the name of the variable referencing the array that is being updated. I suppose you could pass in the "variable path" to the array being augmented.

@Mark,

Agreed; I feel like Adobe has never came out and took a stand on whether or not we *should* use the underlying Java methods. I use them personally, but I'd love to hear a definitive answer.

A while back, I realized that, to some degree, you *have* to use the Java methods on CF objects simply because ColdFusion doesn't allow you to differentiate the two types:

http://www.bennadel.com/blog/1023-ColdFusion-Wants-You-To-Access-The-Underlying-Java-Methods.htm

I also tested this on Vectors as well. Create an instance of a Java Vector and isArray( javaVector ) will return "True".

Since we can't natively differentiate between ColdFusion data structures and Java data structures with "similar" interfaces, it would lead us to the conclusion that ColdFusion wants us to use the underlying Java methods.


Nov 19, 2010 at 4:46 PM // reply »
22 Comments

You know Ben, CF underlying Java core works better for this. ColdFusion arrays are actually an implementation of java list (java.util.List). So all the java list methods can easily be used with CF. So to merge two arrays (which is essentially what you're doing) use the list.addAll() method.

For instance, you have two arrays:

<cfset women = [ "Sarah", "Tricia", "Joanna" ] />
<cfset incomingWomen = [ "Katie", "Jill", "Erica" ] />

Then all you have to do to merge the arrays is

<cfset women.addAll(incomingWomen ) />

Much simpler and cleaner.

I wish I could take credit for it but its based on a blog entry by Rupesh Kumar of Adobe.

http://coldfused.blogspot.com/2007/01/extend-cf-native-objects-harnessing.html

regards,
larry


Nov 19, 2010 at 4:52 PM // reply »
10,743 Comments

@Larry,

Yeah, that .addAll() method is cool (as I mentioned in my first paragraph :P). That said, thanks for the link to Rupesh's blog. Since he's an Adobe ColdFusion engineer, this looks like a pretty official position that we *can* use the Java methods. Rockin :)


Nov 19, 2010 at 5:33 PM // reply »
10 Comments

Why not use the Java?

1) Well, other coldfusion implementations may not support it (Railo, OpenBD, BD.NET). If you want to be portable across CF runtimes, you're pretty much stuck with plain jane cfml.

2) Adobe might change their API in a future release.Thing is, they could do the same with the CFML. :) That's less likely, but unless they drastically change implementations, I don't see it as a problem.

I've done this with the lists and stuff for years, since the list performance on cf7 and earlier was terrible. cf8 and 9 both improved the situation greatly, so I don't rely on it for list stuff as much anymore.

In fact, I even routinely use undocumented java functions. Typically from within a java library, fronted by a cfc or another facade so other devs don't really have to touch the java.

For example, I use the java jackson library in conjunction with a coldfusion.sql.QueryTable to generate non-messed up json (with the same performance as cf8's native json) and I recently implemented ehcache integration for cf8.

It's been so many years since CF went java, and so many devs are still afraid of it.


Nov 22, 2010 at 6:01 AM // reply »
5 Comments

Hi Ben,
We can also handle the Array append with the help of ArrayToList() and ListToArray() in easy way.

  • <cfset women = [ "Sarah", "Tricia", "Joanna" ] />
  • <cfset incomingWomen = [ "Katie", "Jill", "Erica" ] />
  • <cfset womenList = ArrayToList(women)>
  • <cfset incomingWomenList = ArrayToList(incomingWomen)>
  • <cfset NewWomenList = ListAppend(womenList,incomingWomenList)>
  • <cfset women = ListToArray(NewWomenList)>
  • <cfoutput>
  • Women: #arrayToList( women, " - " )#
  • </cfoutput>


Nov 30, 2010 at 9:32 AM // reply »
1 Comments

I've got several versions of CF to deal with so compatibility is paramount for me. This works great, thanks!


Dec 5, 2010 at 2:48 PM // reply »
10,743 Comments

@Mark,

Yeah, the Java methods are cool. I've often used them when dipping down into String's replaceFirst() and replaceAll() methods. There's always a chance that something will change; but from what I've read, it seems to be generally held as safe to use these kind of approaches.

@Manoj,

You can definitely do that, so long as all of your array contents are simple values. If you had an array of structs, for example, ColdFusion wouldn't be so happy :)

@Frank,

Good stuff.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 16, 2012 at 8:18 PM
Best Of ColdFusion 10 Contest Entry - HTML Email Utility
Just found this, looks good! I'm trying to run it on local, it's the 64bit version and I'm experiencing horrible lag. On average the generate.cfm processes the content change in 60-90 seconds. I've ... read »
May 16, 2012 at 6:40 PM
Maintaining Sessions Across Multiple ColdFusion CFHttp Requests
I am trying to integrate this CFHTTPsession into an application that will log into zeekrewards.com to post ads and I am not having any luck. The code works perfectly for logging into other websites, ... read »
May 16, 2012 at 2:44 PM
Creating A Sometimes-Fixed-Position Element With jQuery
Thank you, very useful technique! Worked like a charm. ... read »
May 16, 2012 at 1:58 PM
Movies As A Religious Experience
Acting can, in a way, ruin the movie-goer's experience. I used to be able to get so caught up in movies and their plots, and totally engaged. But lately, I haven't been able to as much with a lot o ... read »
May 16, 2012 at 1:52 PM
The Science Of Optimal Post-Exercise Nutrition
children of this age eat very less vegetables so u can opt for salads they will like it also carrot ,cucumber,onion and as far as pulses are concerned u can boil them ,give him along with mashed rice ... read »
May 16, 2012 at 1:34 PM
Strange ColdFusion JRUN Stack Overflow Error
Hey, Recently I updated my jrun4 using the latest updater 7 and now i am having memory issues :(:(:( any help is appreciated ... read »
May 16, 2012 at 9:56 AM
ColdFusion 10 Beta, Apache Tomcat, And Symbolic Links On Mac OSX
Hi, Now that ColdFusion 10 is out I have stumbled over this as well and I cannot figure out the proper solution. We're running virtual hosts via Apache2; the ColdFusion-applications store their fil ... read »
May 15, 2012 at 6:03 PM
Movies As A Religious Experience
@Ben, I don't know whether you'd consider this a religious observation, but it seems to me, in a sense, movies multiply how many lives we get to have. Each movie is like a little extra life we get ... read »