ホーム >> 左脳Script >> Adobe Flash >> Action Script >> 配列の添え字についての検証

配列の添え字についての検証


Action Script 3.0 では配列管理のトップレベルクラスとして Arrayクラス が知られています。
この Arrayクラス、インデックス(添え字)を真面目に0から振らなくても配列として機能する、C言語からの移民からすれば、なんとも便利で不可解な動作をするのですが、仕組みがわかればソレほど難しくもありません。

種を明かせば、インデックスは文字列で管理され、その実情は連想記憶配列と言ってもいい仕組みなのです。

そんな仕組みですから速度にも限界があり、それを解決する為に Flash10 以降では Vectorクラス が導入されました。
ここでは Vectorクラス については説明しません。各自「as3 Vector」等のキーワードで検索してみてください。


柔軟な Array インデックス

インデックスにどんな数値を指定しても、結局(ある程度は正規化されている)文字列になる為、 数値とデータを関連付ける事が大変容易になっています。


var test:Array = new Array();
test[100] = "百";
test[123456789] = "大きい";
test[-56.3] = "マイナス";

まぁ普通の使い方をしていれば、何らかの整数値とデータを対にするのが一般的かと思います。

var comments:Array = new Array();
comments[3265478] = "ちょwwwおまwwwwww";
comments[3265479] = "これはないwww";
comments[3255630] = "才能の無駄遣いwww";
この例のように大きなインデックスをしようした場合のメソッドへの影響を検証してみました。


Array.sort

検証コード。3つのデータを文字列の長さでソートする単純な物です。

var test:Array = new Array();

test[3265478] = "ちょwwwおまwwwwww";
test[3265479] = "これはないwww";
test[3255630] = "才能の無駄遣いwww";

var st:int = getTimer();
test.sort(function (a:String, b:String):int 
{
    var av:int = a.length;
    var bv:int = b.length;
    if (    av > bv )   return  -1;
    if (    av < bv )   return  1;
    return  0;
});
var sp:int = getTimer() - st;
for(var i:* in test)
{
    trace("test[" + i + "]=" + test[i]);
}
trace("time = " + sp +"msec.");
実際に上記のコードは私の環境では、657msecと出ました。

たかが3つのデータのソートにしては時間がかかりすぎですね。
試しにデータをこのようにして見ると・・・

test[1] = "ちょwwwおまwwwwww";
test[4] = "これはないwww";
test[5] = "才能の無駄遣いwww";
結果は 0msec. と出ました。

インデックスの数値の大きさにモロに影響があります。 インデックスにうっかり 20000000 とか大きな値を使うと、とんでもない事になりますね。
また、インデックスに正の整数以外の物(マイナス値、小数点数、完全な文字列、等)を使うと、ソートの対象外になるようです。


ひと工夫

前述の例のように、大きなインデックスを持つデータをソートしたい場合、以下のようにデータ構造を工夫する必要があります。

var test:Array = new Array();

test[0] = { id:3265478, chat:"ちょwwwおまwwwwww" };
test[1] = { id:3265479, chat:"これはないwww" };
test[2] = { id:3255630, chat:"才能の無駄遣いwww" };

var st:int = getTimer();
test.sort(function (a:Object, b:Object):int 
{
    var av:int = a.chat.length;
    var bv:int = b.chat.length;
    if (    av > bv )   return  -1;
    if (    av < bv )   return  1;
    return  0;
});
var sp:int = getTimer() - st;
for(var i:* in test)
{
    trace("test[" + i + "]={id:" + test[i].id +",chat:" + test[i].chat + "}");
}
trace("time = " + sp +"msec.");
結果は 0msec. と出ました。


Array.map

こちらも、配列を総なめする上に、演算結果を配列に出来る使いどころにコツが要るメソッドです。

こんなコードを書くと・・・

var test:Array = new Array();

test[3265478] = "ちょwwwおまwwwwww";
test[3265479] = "これはないwww";
test[3255630] = "才能の無駄遣いwww";

var m:Array;
var st:int = getTimer();
m = test.map( function(iter:String, index:int, arr:Array):int
{
    return  iter.length;
});
var sp:int = getTimer() - st;
trace(m);
trace("time = " + sp +"msec.");
要素のプロパティにアクセスする「return iter.length」で、

[Fault] exception, information=TypeError: Error #1009: Cannot access a property or method of a null object reference.

発生。
念のため「trace(index);」を入れて確認すると、予想通り 0 から始まっています。

これも結局は、Array.sort と同じ処置で対応しないと、とんでもないループ回数になってしまう事でしょう。
その前に、インスタンスが無い要素(null)に対してアクセスするので、上記のようなエラーでまともに動きませんが。


結論

大きな数値を ID とするデータは、ID を直接配列のインデックスにしてはならない。
ここで取り上げたメソッド以外にも、これと同じような動作をする物が在るでしょう。 しっかりと「データ構造」「メソッドの動作」を理解している分には問題ありませんが、

そのまま適当にコーディングすると、大変な事になりますよ・・・




トラックバック(0)

トラックバックURL: http://n-yagi.0r2.net/sanoupulurun/mt-tb.cgi/252

コメントする

ホーム >> 左脳Script >> Adobe Flash >> Action Script >> 配列の添え字についての検証

アーカイブ

このブログ記事について

このページは、n-yagiが2010年1月18日 20:17に書いたブログ記事です。

ひとつ前のブログ記事は「XML フィルターについて」です。

次のブログ記事は「XML でソートするには」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Creative Commons License
このブログはクリエイティブ・コモンズでライセンスされています。