如何使用CFML测试两个数组是否相同?
使用CFML(ColdFusion标记语言,也称为ColdFusion),如何比较两个单维数组是否相同?
解决方案
回答
有一种非常简单的方法,可以使用CFML的底层Java比较两个数组。根据Adobe Rupesh Kumar最近的博客(http://coldfused.blogspot.com/),ColdFusion数组是Java列表(java.util.List)的实现。因此,所有Java列表方法均可用于CFML数组。
因此,要比较2个数组,我们需要做的就是使用equals方法。如果数组相等,则返回YES,否则返回NO。
<cfset array1 = listToArray("tom,dick,harry,phred")/> <cfset array2 = listToArray("dick,harry,phred") /> <cfset array3 = listToArray("tom,dick,harry,phred")/> <cfoutput> Array2 equals Array1 #array2.equals(array1)# (returns a NO) <br/> Array3 equals Array1 #array3.equals(array1)# (returns a YES) <br/> </cfoutput>
回答
cflib中的arrayCompare()用户定义函数应执行此操作
http://cflib.org/index.cfm?event=page.udfbyid&udfid=1210
回答
Jasons的答案当然是最好的,但是我之前做过的事情是对已序列化为WDDX的对象执行哈希比较。
此方法仅对相对较小的数组有用,但是如果我们想仅将其保留为CFML,则这是另一种选择。我们还可以将方法应用于其他数据类型,这也带来了好处。
编辑:Adams完全正确(如我们从他的数字中可以看到的),JSON不仅在这种情况下而且对于一般的序列化来说都更加经济。在我的辩护中,我坚持使用没有内置JSON函数的CFMX 6.1,并试图避免使用外部库。
回答
为了建立James的答案,我认为JSON可能比WDDX更可取。实际上,它被证明效率更高。比较哈希值并不昂贵,但是序列化数据然后生成哈希值可能会比较大(对于更大和/或者更复杂的数据结构)。
<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>
这是上面的代码在我的机器上生成的输出:
JSON: done. len=7460 hash=5D0DC87FDF68ACA4F74F742528545B12 JSON: 0ms WDDX: done. len=33438 hash=94D9B792546A4B1F2FAF9C04FE6A00E1 WDDX: 47ms
尽管我要序列化的数据结构相当复杂,但可以很容易地认为它很小。这应该使WDDX上的JSON序列化效率更加可取。
无论如何,如果我尝试使用哈希比较来编写" compareAnything"方法,我将在WDDX上使用JSON序列化。
回答
不久之前,我一直在研究使用CF的本机Java对象,这个问题使我想起了一些博客文章,这些文章是我搜索后加为书签的。
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. Merge two arrays Append an array in the middle of another array Search for an element in an array Search array 1 to see if array 2's elements are all found Equality check Remove elements in array 1 from array 2 From: http://coldfused.blogspot.com/2007/01/extend-cf-native-objects-harnessing.html
我发现的另一个资源展示了如何使用本机Java Array类来获取唯一值并创建自定义排序函数,以防万一需要对日期数组进行排序。
http://www.barneyb.com/barneyblog/2008/05/08/use-coldfusion-use-java/
第二个链接包含指向其他文章的链接,作者在其中显示了如何本地使用其他Java类来获得功能或者加快CF函数的速度。
回答
所有这些解决方案都检查两个数组是否相等。他们不检查它们是否是同一对象。我知道在本机CF中做到这一点的唯一方法是以某种方式更改对象,并查看两个引用是否都已更改。
我还认为我们应该警惕依靠CF实现某些java类或者公开方法。这些很容易改变。
至于比较两个数组以查看内容是否相同,为什么不只是
检查长度(如果不同则返回false)
如果从1到数组len的长度相同,并检查元素是否相同,则返回false;否则返回false。
这将适用于简单的值。
回答
假设数组中的所有值都是简单值,最简单的方法可能是将数组转换为列表,然后进行字符串比较。
<cfif arrayToList(arrayA) IS arrayToList(arrayB)> Arrays are equal! </cfif>
不如其他解决方案提供的优雅,但非常简单。