Skip to main content
Ben Nadel at RIA Unleashed (Nov. 2010) with: David Crouch
Ben Nadel at RIA Unleashed (Nov. 2010) with: David Crouch

Appending One Array To Another With ArrayAppendAll() In ColdFusion

By
Published in Comments (9)

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.

Want to use code from this post? Check out the license.

Reader Comments

167 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.

15,841 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:

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.

30 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

15,841 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 :)

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.

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>
1 Comments

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

15,841 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.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel