JavaScript オブジェクトからチェックサムを作成する必要があります。
残念ながら、JavaScript のオブジェクトの順序付けのために、これを実現する簡単な方法はないようです。たとえば、次のオブジェクトを取り上げます。
var obj1 = {type:"cake",quantity:0}
, obj2 = {quantity:0,type:"cake"};
これらのオブジェクトはデータが等しいと考えており、チェックサムを同じにしたいと考えています。オブジェクト内のデータが同じである限り、オブジェクトの順序は気にしません。
悲しいかな、JSON.stringify
それらの両方は実際には等しくありません。オブジェクトのチェックサムを作成する唯一の方法はその文字列表現を使用することであり、JSON.stringify
-ed 表現が等しくないため、私のチェックサムは等しくなりません!
私が思いついた解決策の 1 つは、次のように、定義済みのスキーマに基づいてオブジェクトを再作成することです。
var schema = ["type","quantity"];
function sortify(obj,schema){
var n={};
for(i in schema)
n[schema[i]]=obj[schema[i]];
return n
}
実行JSON.stringify(sortify(obj1,schema))==JSON.stringify(sortify(obj2,schema))
すると戻りtrue
ます...ただし、新しいオブジェクトを作成し、データをシャッフルするという代償が伴います。
JSON.stringify
私のもう 1 つの解決策は、このメソッドを、事前定義されたスキーマからキーを選択し、それらの値を文字列化して結合するメソッドに置き換えることです。関数は次のとおりです。
function smarterStringify(obj,schema){
var s="";
for(i in schema)
s+=JSON.stringify(obj[schema[i]]);
return s
}
このメソッドが正しい JSON を返さないという事実を無視すると (これは、私がやろうとしていることの例としては十分に近いものです)、最初の方法よりも速度が大幅に改善されています (少なくとも私の Chrome OS ブラウザーでは、ここで自分で確認できます: http://jsperf.com/sort-then-json-stringify-vs-smarter-stringify )、そしてもちろん、2 つのオブジェクト文字列表現が等しくなります!
しかし、何かを見逃していたのではないかと思っていたのですが、a) JavaScript GC を異常なケースに追い込んだり、b) あまりにも多くの文字列連結を実行したりしなかった、このようなもののための組み込みメソッドがずっとあったのです。私はむしろそれらをしたくありません。