その昔、CGIをゴリゴリ書いていた時に、Perl言語を使っていたんですが、
if文の比較処理で"=="を使わずに"eq"を使うのがどうも使いづらいな〜と思っていたら、
shellの比較文でも文字列は"eq"を使っているし、
他の言語でも変数タイプに応じて比較は"=="だけでないほうが一般的なのだと気が付きました。
しかしjavascriptにはeq比較が無くて、案の定比較処理が弱いという事を思い知りました・・・
javascriptにおける配列の比較は難点だった事
配列を比較するという処理をこれまであまりやって来たことがなかったので、滅多に無い処理であることは間違いないが、それであるがゆえに、配列比較処理が発生した時に困るし、どのようにすればいいかという代案もない状態は非常に難易度が高い。
そもそも、配列の比較ってどういう時にやる処理なのかというと、少し大きめのシステム開発をする時に、新たに作り出したデータがすでにメモリに格納しているデータと同じかどうかを判定したい場合などに、行う比較処理で、PHPやJAVAなどの場合であれば、SQLにデータ保存をして、比較処理をしがちがだ、javascriptはローカルストレージやcookie、メモリ格納、またはjsonデータぐらいのため、自力で比較をしなければいけない。
そして、javascriptは、変数方の"object"が配列と連想配列などになっているのだが、objectを比較すると、全く同じデータ出ない限り、falseが返ってきてしまう。
var a = [{a:1},{b:2},{c:3}];
var a1 = {a:1};
a[0] == a1
> false
a1 == a1
> true
上記のような感じである。
これは由々しき事態という事で、配列同士の比較を厳密に行ってみたいと思います。
単純な配列比較はJSON変換で十分
上記のような場合の比較は下記のようにすると、いいでしょう。
JSON.stringify(a[0]) == JSON.stringify(a1)
> true
jsonとして文字列化してしまうと、簡単に比較できてしまうのですが、これは内容が1つだけの変数で行ったので問題はないのですが、配列には並び順版が存在するため、順番が違う配列通しだと、中の値は同じでも"false"になってしまいます。
var b = [1,2,3];
var b1 = [2,3,1];
JSON.stringify(b) == JSON.stringify(b1)
> false
もちろん、並びが違うので厳密に別という判定でいいのですが、連想配列の場合などでは、並び順を無視して比較をしたい場合がある。
var c1 = {a:1,b:2,c:3};
var c2 = {b:2,c:3,a:1};
JSON.stringify(c1) == JSON.stringify(c2)
> false
これはtrueとして判定をしてもらいたい。
連想配列の比較の為のソート関数
連想配列を意識した内容が同じであるかを判定するためのソート処理を行う関数を書いてみました。
function hashSort(val){
// json化して戻すことで、元データの書き換えを防ぐ
var hash = JSON.parse(JSON.stringify(val));
// 連想配列処理
if(typeof hash === "object"){
var flg = 0;
for(var i in hash){
if(typeof hash[i] === "object"){
hash[i] = JSON.stringify(hashSort(hash[i]));
}
flg++;
}
if(flg <= 1){console.log(hash);
return JSON.stringify(hash)}
if(typeof hash.length === "undefined"){
var keys = Object.keys(hash).sort();
var newHash = {};
for(var i=0; i<keys.length; i++){
newHash[keys[i]] = hash[keys[i]];
}
return newHash;
}
else{
hash.sort(function(a,b){
if( a < b ) return -1;
if( a > b ) return 1;
return 0;
});
return hash;
}
}
// その他タイプはそのまま返す
else{
return hash;
}
}
この関数を使って判定すると、以下のようになります。
JSON.stringify(hashSort(c1)) == JSON.stringify(hashSort(c2))
> true
配列をソートする時につかうsort()関数が連想配列で使用するとエラーになるので、Object.keysでキーソートをかけているところがポイントです。
これでもう少しだけコーディングが便利になるかもね。
0 件のコメント:
コメントを投稿