CFML(ColdFusion Markup Langauge、別名ColdFusion)を使用して、2つの単一次元配列が同じであるかどうかをどのように比較できますか?
7 に答える
CFMLの基盤となるJavaを使用して2つの配列を比較する非常に簡単な方法があります。AdobeのRupeshKumarによる最近のブログ(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>
James の回答に基づいて、WDDX よりも JSON の方が適していると考えました。実際、それはかなり効率的であることが証明されています。ハッシュの比較はそれほど高価ではありませんが、データをシリアル化してからハッシュを生成することは (より大きなデータ構造やより複雑なデータ構造の場合) 可能性があります。
<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 シリアル化を使用することになります。
cflib の arrayCompare() ユーザー定義関数で実行する必要があり ます http://cflib.org/index.cfm?event=page.udfbyid&udfid=1210
配列内のすべての値が単純な値であると仮定すると、最も簡単な方法は、配列をリストに変換して文字列比較を行うことです。
<cfif arrayToList(arrayA) IS arrayToList(arrayB)>
Arrays are equal!
</cfif>
提供されている他のソリューションほどエレガントではありませんが、非常にシンプルです。
ジェイソンの答えは確かに最高ですが、私が以前に行ったことは、WDDX にシリアル化されたオブジェクトに対してハッシュ比較を実行することです。
この方法は、比較的小さな配列の場合にのみ役立ちますが、純粋な CFML を維持したい場合は別のオプションです。また、メソッドを他のデータ型にも適用できるという利点もあります...
編集:Adamsの完全な権利(彼の数字からわかるように)-JSONは、この状況だけでなく、一般的なシリアライゼーションでもはるかに経済的です。私の弁護では、JSON関数が組み込まれていないCFMX 6.1を使用して立ち往生しており、外部ライブラリを回避しようとしていました。
しばらく前に CF のネイティブ Java オブジェクトの使用を検討していたときに、この質問を見て、検索の結果としてブックマークしたいくつかのブログ記事を思い出しました。
ColdFusion 配列は、実際には Java リスト (java.util.List) の実装です。したがって、すべてのリスト メソッドは実際には Array で使用できます。CF は配列関数を使用してほとんどのリスト機能を提供しますが、CF 関数で直接実行できない Java リストで可能なことはほとんどありません。
- 2 つの配列をマージする
- 別の配列の途中に配列を追加する
- 配列内の要素を検索する
- 配列 1 を検索して、配列 2 の要素がすべて見つかったかどうかを確認します
- 等価チェック
- 配列 2 から配列 1 の要素を削除する
から: 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/
この 2 番目のリンクには、他の Java クラスをネイティブに使用して CF 関数よりも機能または速度を向上させる方法を著者が示している他の投稿へのリンクが含まれています。
これらのソリューションはすべて、2 つの配列が等しいことを確認します。それらが同じオブジェクトであることを確認しません。ネイティブ CF でそれを行う唯一の方法は、何らかの方法でオブジェクトを変更し、両方の参照に変更があるかどうかを確認することです。
また、特定の Java クラスを実装したり、メソッドを公開したりする CF に依存することにも注意する必要があると思います。これらは変更される可能性があります。
内容が同じかどうかを確認するために 2 つの配列を比較する場合、長さをチェックしない理由 (異なる場合は false を返す) 1 から配列 len までの長さが同じ場合、要素が同じであることを確認し、要素が同じ場合はブレークして false を返します。ではありません。
これは、単純な値に対して機能します。