35.NaNの謎

NaNってナンだ?

配列がらみになるのですが、ちょっと引っかかったところがあったので、そのあたりをまとめておきます。

上のオヤジギャグを書きたかっただけ、という話もありますが、、、?!

定義していない要素をいじる

配列を扱っていると定義していないのをうっかり計算に入れてしまうことってありません?

え?ない?だから、ここでない、って言ったら話がすすまないでしょ?ウソでも「そうですね」と答えるのが大人のやさしさってもんです。

では、基本的なところから確認してみます。

var array:Array=[0,1];//配列の定義

trace(array[0]);//0
trace(array[1]);//1
trace(array[2]);//undefined

array[2]は定義されていないのでundefinedとなるのはOKです。納得であります。

では、array[2]+=1とすれば?

演算があれば0として扱ってくれる、、、?

いえいえ、結果は以下のようになります。

trace(array[2]);//undefined
array[2]+=1;
trace(array[2]);//NaN

さっきはundefinedだったのが、NaNになりました。

なんだかわかりませんが、とりあえず0として扱われることはないようです。

まあ納得ですね。

うっかり計算に入れてしまってるのだから、ここは変な値を返してほしいですからね。

ちなみにNaNは Not a Number のことだそうです。

Boolean型で評価すると

よく if (array[2]){ ってな感じでtrueかfalseかで評価することってありますよね。

先ほどの、undefinedだの、NaNだのはどうなるんでしょうか?

var array:Array=[0,1];//配列の定義

if (array[2]) {//array[2]はundefined
trace("true");
}else{
trace("false");//falseが表示されます
}

array[2]+=1;//これでNaN

if (array[2]) {
trace("true");
}else{
trace("false");//これもやっぱりfalseが表示されます
}

どちらも false になるのは、納得ですね。

0と区別するには?

上で中身がないのがfalseになるのはいいんですけど、0もfalseと評価されますよね。

よって、この配列に中身はあるのか?って評価するのに

if (array[ii]) {
//処理
}

という書き方はまずいことになります。0の場合に処理されませんので。

では、、、

if ( (array[ii])||(array[ii]==0)) {
//処理
}

まあこれでも用は足せますが、、、あんまり人に見られたくないですね(^^;

こういう便利な関数がありますのでこっちの方が恥ずかしくないかもしれません。

if (!isNaN(array[ii])) {
//処理
}

NaNを含んだ場合のソート

では、うっかりNaNを含む配列をソートしたら、という場合。

配列は値段(price)と名称(name)を持つオブジェクト形式とします。

var array:Array=new Array();

array.push( {price:150 , name:"apple"} );
array.push( {price:100 , name:"banana"} );
array.push( {price:NaN , name:"chocolate"} );//チョコの値段はNaN

このように定義すると array[0].name とか array[1].price という感じでアクセスできますよね。

ここでは、テストのために3つめの chocolate の price を NaN と設定しています。

ではこれを price でソートして値を確認してみます。

//数値かつ値が大きい順でソート
array.sortOn("price" , Array.DESCENDING|Array.NUMERIC);

//確認
trace(array[0].name+" = "+array[0].price);//chocolate = NaN
trace(array[1].name+" = "+array[1].price);//apple = 150
trace(array[2].name+" = "+array[2].price);//banana = 100

え?

chocolate の NaN が一番高い???

値が小さい順でやっても chocolate が一番高いと評価されます。

このようなソートの対象に NaN を含む場合に一番値が大きいとするのがいいのか、いつもの如く(?)無言で停止するのがいいのか私にはわかりませんが、、、

なぜこうなるかは謎ですが、ともかく要注意であります。

34.SWFをコンパイル時にEmbedする←