tags:

views:

866

answers:

7

Using CFML (ColdFusion Markup Langauge, aka ColdFusion), how can you compare if two single dimension arrays are the same?

+7  A: 

There's a very simple way of comparing two arrays using CFML's underlying java. According to a recent blog by Rupesh Kumar of Adobe (http://coldfused.blogspot.com/), ColdFusion arrays are an implementation of java lists (java.util.List). So all the Java list methods are available for CFML arrays.

So to compare 2 arrays all you need to do is use the equals method. It returns a YES if the arrays are equal and NO if they are not.

Array2 equals Array1 #array2.equals(array1)# (returns a NO)
Array3 equals Array1 #array3.equals(array1)# (returns a YES)

Jason
lots of times people forget that we can dip to Java to get things done. Excellent suggestion.
rip747
+2  A: 

The arrayCompare() user-defined function at cflib should do it http://cflib.org/index.cfm?event=page.udfbyid&udfid=1210

philcruz
+1  A: 

Jasons answer is certainly the best, but something I've done before is performed a hash comparison on objects that have been serialised to WDDX.

This method is only useful for relatively small arrays, but it's another option if you want to keep it purely CFML. It also has the benefit that you can apply the method to other data types as well...

Edit: Adams' entirely right (as you can see from his numbers) - JSON is much more economical, not only in this situation, but for serialization in general. In my defense I'm stuck using CFMX 6.1 that has no inbuilt JSON functions, and was trying to avoid external libs.

James Marshall
+2  A: 

To build on James' answer, I thought that JSON might be preferrable over WDDX. In fact, it proves to be considerably more efficient. Comparing hashes is not that expensive, but serializing the data and then generating the hash could be (for larger and/or more complex data structures).

<cfsilent>
    <!--- create some semi-complex test data --->
    <cfset data = StructNew() />
    <cfloop from="1" to="50" index="i">
     <cfif variables.i mod 2 eq 0>
      <cfset variables.data[variables.i] = StructNew()/>
      <cfset tmp = variables.data[variables.i] />
      <cfloop from="1" to="#variables.i#" index="j">
       <cfset variables.tmp[variables.j] = 1 - variables.j />
      </cfloop>
     <cfelseif variables.i mod 3 eq 0>
      <cfset variables.data[variables.i] = ArrayNew(1)/>
      <cfset tmp = variables.data[variables.i] />
      <cfloop from="1" to="#variables.i#" index="j">
       <cfset variables.tmp[variables.j] = variables.j mod 6 />
      </cfloop>
      <cfset variables.data[variables.i] = variables.tmp />
     <cfelse>
      <cfset variables.data[variables.i] = variables.i />
     </cfif>
    </cfloop>
</cfsilent>

<cftimer label="JSON" type="inline">
    <cfset jsonData = serializeJson(variables.data) />
    <cfset jsonHash = hash(variables.jsonData) />
    <cfoutput>
     JSON: done.<br />
     len=#len(variables.jsonData)#<br/>
     hash=#variables.jsonHash#<br />
    </cfoutput>
</cftimer>
<br/><br/>
<cftimer label="WDDX" type="inline">
    <cfwddx action="cfml2wddx" input="#variables.data#" output="wddx" />
    <cfset wddxHash = hash(variables.wddx) />
    <cfoutput>
     WDDX: done.<br />
     len=#len(variables.wddx)#<br/>
     hash=#variables.wddxHash#<br />
    </cfoutput>
</cftimer>

Here's the output that the above code generates on my machine:

JSON: done.
len=7460
hash=5D0DC87FDF68ACA4F74F742528545B12
JSON: 0ms

WDDX: done.
len=33438
hash=94D9B792546A4B1F2FAF9C04FE6A00E1
WDDX: 47ms

While the data structure I'm serializing is fairly complex, it could easily be considered small. This should make the efficiency of JSON serialization over WDDX even more preferrable.

At any rate, if I were to try to write a "compareAnything" method using hash comparison, I would use JSON serialization over WDDX.

Adam Tuttle
+2  A: 

I was looking into using CF's native Java objects awhile back and this question reminded me of a few blog posts that I had bookmarked as a result of my search.

ColdFusion array is actually an implementation of java list (java.util.List). So all the list methods are actually available for Array. CF provides most of the list functionality using Array functions but there are few things possible with java list which you can not do directly with CF functions.

  1. Merge two arrays
  2. Append an array in the middle of another array
  3. Search for an element in an array
  4. Search array 1 to see if array 2's elements are all found
  5. Equality check
  6. Remove elements in array 1 from array 2

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

Another resource I found shows how you can use the native Java Array class to get unique values and to create custom sorts functions in case you need to sort an array of dates, for instance.

http://www.barneyb.com/barneyblog/2008/05/08/use-coldfusion-use-java/

This second link contains links to other posts where the author shows how to use other Java classes natively to gain either functionality or speed over CF functions.

kooshmoose
+1  A: 

All of these solutions check that two arrays are equal. They don't check that they are the same object. The only way I know to do that in native CF is to change the object in some way and see if both references have the change in.

I also think that you should be wary of relying on CF implementing certain java classes or exposing methods. These are liable to change.

As for comparing two arrays to see if the contents is the same, why not just Check the length (if different return false) If the lengths are the same from 1 to array len and check the elements are the same break and return false if they are not.

This will work for simple values.

+1  A: 

Assuming all of the values in the array are simple values, the easiest thing might be to convert the arrays to lists and just do string compares.

<cfif arrayToList(arrayA) IS arrayToList(arrayB)>
    Arrays are equal!
</cfif>

Not as elegant as other solutions offered, but dead simple.

Al Everett
Assuming simple arrays, this is easily the quickest and simplest solution
Jason