If you have ever tried to find a simple value in an array, you will quickly find that ColdFusion does not have any built in ArrayFind() method. As I am quickly finding out, it is amazing that ColdFusion is built on top of Java 2 as Java has such methods that we can access directly.
Before we look at the sleek and sexy Java methods, let's take a look at how we would traditionally find a simple value in an array. There are two methods which vary in complexity and speed. The simplest is to convert to a list:
Launch code in new window » Download code as text file »
This can be a slow method. You rarely ever want to convert an array to a list. You also now have to worry about list delimiters within the array values. This may or may not be a concern. If you don't want to go the list route, the other method would be to create a user defined function (UDF) that loops through the array comparing values:
Launch code in new window » Download code as text file »
This can be very fast and efficient, but it requires more code.
However, as I mentioned before, because ColdFusion arrays are really the Java object coldfusion.runtime.Array, we have access to a host of Java methods directly accessible from the ColdFusion array object instance. Of particular interest are the methods:
Now, remember, since these are built into the ColdFusion objects, we can call them directly. Let's set up some test code:
Launch code in new window » Download code as text file »
Here we set up a one-dimensional array as well as a collection object (java.util.ArrayList). We have set up the collection to test some of the functionality a little farther down on the page.
This takes an object and returns true if the object exists in the array (false if not). The caveat here is that if you have an array of numeric values, Java sees them as strings (this will be discussed later on). Therefore, when searching for values, you must explicitly send them as strings.
Launch code in new window » Download code as text file »
This will return true because Laura is in the array. Notice that I am explicitly casting to string for Java use. This is GOOD practice as ColdFusion is not always sure what to do when it comes to type conversions.
This takes a collection object and determines if every one of the items exists in the array.
Launch code in new window » Download code as text file »
Notice that we are sending the collection (java.util.ArrayList) that we created above. This will return true as both Kit and Kim exist in the original array.
This takes an object and returns the index of the matching value. Be careful; Java is based at Zero. It is not based at One like ColdFusion. Therefore, non-matching results return a -1, NOT zero.
Launch code in new window » Download code as text file »
Notice again that I am always explicitly casting the string. This will return 3 as Heather is the fourth value in the list. In Java, the fourth value, indexed starting at zero, will return 3.
Launch code in new window » Download code as text file »
This will return -1 as Bobby Jo is NOT in the original list.
This will get the last index of the given value in the array.
Launch code in new window » Download code as text file »
This will return 1 and 6 respectively.
How easy is that? All this time (since ColdFusion MX) there have been UDF's written for the very purpose of mimicking something that was already built into the language, albeit hidden from the surface through the ColdFusion facade.
Now, I have only tested this using simple values. I am not sure how this would work using complex objects such as structs. I am guessing that structs of simple values would work fine but no promises. After all, the IndexOf() and Contains() methods do NOT take strings. They take OBJECTS. That is for flexibility.
Just to cover the string vs. number caveat. Assuming we have the following array:
Launch code in new window » Download code as text file »
... the following will NOT find a value:
Launch code in new window » Download code as text file »
... since it is asking for a numeric match. However, the following WILL find a value:
Launch code in new window » Download code as text file »
This is because the original values of the array are stored as strings, even though we told them to be numbers. All simple values are stored as strings. You can overcome this by forcing the initial array to be set using JavaCast() and numeric values:
Launch code in new window » Download code as text file »
Once you have this, you can search for numeric values. In fact, you have to search for numeric values. Searching for strings at this point will not yield any matches as they did above.
So there you have it. Go explore the wonderful marriage of ColdFusion and Java. This intended for mature audiences only as it might get hot and steamy in that bed ;)
If you want to see what is available in the coldfusion.runtime.Array object, here are the class methods and constructors complete with parameter types and return types:
| | | | ||
| | ![]() | | ||
| | | |
Download Code Snippet ZIP File
Comments (2) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Good post! Its worth noting that because you're using java methods any string searches are case sensitive. So indexOf("Kim") returns 1 but indexOf("KIM") returns -1.
Another great trick is using the underlying java class to supplement ColdFusion's list functions. One list function I've always wanted to see in CF is the ability to grab a portion of a list. You can use the subList() method to do just that.
<!--- return first two elements of arrNums --->
<cfset subList = arrayToList(arrNums.subList(0, 2))>
<cfoutput>#subList#</cfoutput>
Just remember the indexes are zero based and the fromIndex is inclusive while the end index is exclusive.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html
Posted by jM on Nov 19, 2006 at 2:01 AM
jM,
Thanks for the link and the solid tip. There are definitely times when it would be nice to get a good sub-list. Sweet.
Posted by Ben Nadel on Nov 20, 2006 at 7:49 AM