A while back, I discovered that splitting a string into an array using the Java String::Split() method produced what appeared to be a ColdFusion array, but what was, in fact, a read-only Java array (at least from the ColdFusion perspective). Under the hood, ColdFusion arrays are really collection objects, not true arrays. Because of this, ColdFusion does not inherently resize or set values into Java arrays.
I have always knowm that to get around this, you could create a ColdFusion array, then loop over the Java array and copy the values:
Launch code in new window » Download code as text file »
But this always seems like such a ganky way of doing it. I had hoped there was a more elegant solution, but never really look the time to look it up. Well, finally motivated by Rob Marchetti's comment on my previous post on the subject matter, I figured I would finally look into it.
Just to recap, when you split a string using the String::Split() method, you get what looks like an array:
Launch code in new window » Download code as text file »
When we CFDump that out, we get:
| | | | ||
| | ![]() | | ||
| | | |
Looks good, right? Sure, but then, when we try to go and alter it, as we could any other ColdFusion array:
Launch code in new window » Download code as text file »
... we get the following ColdFusion error:
The Coldfusion function [ArrayAppend] is not supported on this object. The Coldfusion function [ArrayAppend] is not supported on an object of type [coldfusion.runtime.Cast$1]. <br>For Example: XML objects can be operated on by a subset of the Struct and Array functions but not all.
So our goal now becomes to convert this string array into a ColdFusion collection "array." As it turns out, this can be done in a two part process - converting the array into a list, which supports the Java Collection interface, and then add that list to an existing ColdFusion array.
Let's take a look at how to convert the Java array into a List. Using the Java Array utility class, we can use ColdFusion to manipulate Java arrays. In this case, we are going to use the AsList() method to convert the Java array to a List object:
Launch code in new window » Download code as text file »
When we CFDump that List object out, we get:
| | | | ||
| | ![]() | | ||
| | | |
Be careful! Again, this object looks like a ColdFusion array, but it is not. If we tried to modify it:
Launch code in new window » Download code as text file »
... we get the following ColdFusion error:
The Coldfusion function [ArrayAppend] is not supported on this object. The Coldfusion function [ArrayAppend] is not supported on an object of type [java.util.Arrays$ArrayList]. <br>For Example: XML objects can be operated on by a subset of the Struct and Array functions but not all.
Don't worry, we are almost there. The List object that we have now created supports the Java Collection interface. If you have messed around with any of the underlying Java method of ColdFusion objects, you might know that the ColdFusion Array (collection) has a method called AddAll(). AddAll() takes a Collection-interfaced object and adds all of its items to the ColdFusion array:
Launch code in new window » Download code as text file »
When we run the above code, we get no ColdFusion errors and our resultant array looks like this:
| | | | ||
| | ![]() | | ||
| | | |
Ok, so that's a bit of a process with a few steps. However, we can "simplify" and by that I mean condense the code into something that might be considered a little more manageable:
Launch code in new window » Download code as text file »
That's not the easiest thing to read, but to me, it is still a little more elegant that looping over the array and copying over each item (as we did at the beginning of this post). I think the best solution would be for ColdFusion to update their Array wrapper and allow the AddAll() method to accept an array. But for now, this will work.
Download Code Snippet ZIP File
Comments (8) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Ben...
You should submit this to Adobe. Maybe we'll get lucky and they can get it into the final release of Scorpio.
Posted by Andy Matthews on Jun 7, 2007 at 10:06 AM
Why wouldn't you just use listtoarray("foo bar","baz qux") instead?
Posted by Lars on Jun 7, 2007 at 10:40 AM
@Lars: because listToArray() ignores empty list elements. using the split() method works around this... to a degree. ben is addressing the fact that the resulting array is readonly.
the other issue to address is that split() still ignores empty list elements at the end of the list. rupesh kumar addressed that in his blog post here: http://coldfused.blogspot.com/2007/06/listtoarray-with-empty-elements-part-ii.html
Posted by charlie griefer on Jun 7, 2007 at 12:21 PM
if you use split( ",", -1) this should catch any trailing empty lists at the end... i think... i haven't tested this though. :)
Posted by Andrew Clark on Jun 7, 2007 at 12:59 PM
Guys, let's not forget there are many ways to get a Java array. Using the Split() method is just one of them. Many of the Java objects and interfaces have methods that return stuff as arrays. The focus here was on getting those into ColdFusion "array" form... the focus was not meant to be on Split(). That's just happens to be an easy one to use, but I could have just as easily when with String::ToCharArray().
@Andy,
I will do that, I think this is something that could be cool and mostly likely is very easy to implement.
Posted by Ben Nadel on Jun 7, 2007 at 1:32 PM
@Ben and Andy,
We heard it and included it in CF8 :-) I blogged about it a little while back.
http://coldfused.blogspot.com/2007/07/listtoarray-in-coldfusion-8.html
Posted by Rupesh Kumar on Jul 19, 2007 at 4:24 PM
@Rupesh,
Very cool! I think the ability to keep empty list elements is going to make people very happy :)
Posted by Ben Nadel on Jul 19, 2007 at 4:28 PM
Ben--
This was a life saver. Again, your blog helps the common programmer solve a problem. I really appreciate it.
Tim
Posted by Tim on Jul 25, 2007 at 12:09 AM