結合配列

結合配列は "ハッシュ" または "マップ" とも呼ばれ、値の格納場所を数値のインデックスではなく "キー" によって指定する配列です。結合配列に使用する個々のキーは、それぞれに対応する特定の格納値にアクセスするための一意のストリングです。結合配列は Object クラスのインスタンスであり、したがって、各キーはそれぞれ 1 つのプロパティ名に対応します。結合配列は、キー / 値ペアの集合からなる、ソートされていないコレクションです。結合配列内のキーに何らかの決まった順序があるかのような前提でコードを記述してはなりません。

ActionScript 3.0 では、新たに "ディクショナリ" と呼ばれる高機能な結合配列を使用できるようになりました。ディクショナリは flash.utils パッケージに属する Dictionary クラスのインスタンスであり、任意のデータ型 (通常は Object クラスのインスタンス) をキーとして使用できます。つまり、ディクショナリのキーは String 型の値である必要はありません。

このセクションでは、ストリングのキーを使用した結合配列の作成方法、および Dictionary クラスの使用方法について説明します。

サブトピック

ストリングキーを使用した結合配列
オブジェクトのキーを使用した結合配列

ストリングキーを使用した結合配列

ActionScript 3.0 の結合配列を作成するには 2 つの方法があります。1 つは Object コンストラクタを使用する方法で、これには、オブジェクトリテラルを使用して配列を初期化できるというメリットがあります。Object クラスのインスタンス (汎用オブジェクトとも呼ばれる) は、機能的には結合配列と同じです。汎用オブジェクトの個々のプロパティ名が、格納した個々の値にアクセスするためのキーとして機能します。

次の例では、monitorInfo という名前の結合配列を作成します。オブジェクトリテラルを使用して、2 つのキーと値のペアが指定された配列を初期化します。

var monitorInfo:Object = {type:"Flat Panel", resolution:"1600 x 1200"};
trace(monitorInfo["type"], monitorInfo["resolution"]); 
// 出力: Flat Panel 1600 x 1200

宣言時に配列を初期化する必要がある場合は、次のように、Object コンストラクタを使って配列を作成できます。

var monitorInfo:Object = new Object();

オブジェクトリテラルまたは Object クラスのコンストラクタで配列を作成した後は、角括弧演算子 ([]) またはドット演算子 (.) を使用して新しい値を追加できます。次の例では、monitorArray に新しい値を 2 つ追加します。

monitorInfo["aspect ratio"] = "16:10"; // この記述は誤り。空白を使用しないこと
monitorInfo.colors = "16.7 million";
trace(monitorInfo["aspect ratio"], monitorInfo.colors);
// 出力: 16:10 16.7 million

この例で、aspect ratio というキーの名前には空白文字が含まれています。角括弧演算子ではこのような名前も使用できますが、ドット演算子で使用するとエラーになります。空白文字を含んだキー名を使用することはお勧めしません。

結合配列を作成するもう 1 つの方法は、Array コンストラクタを使用し、それから角括弧演算子 ([]) またはドット演算子 (.) で配列にキー / 値ペアを追加する方法です。結合配列を Array 型として宣言した場合、オブジェクトリテラルで配列を初期化することはできません。次の例では、monitorInfo という名前の結合配列を Array コンストラクタで作成し、type および resolution という 2 つのキーとそれぞれに対応する値を追加します。

var monitorInfo:Array = new Array();
monitorInfo["type"] = "Flat Panel";
monitorInfo["resolution"] = "1600 x 1200";
trace(monitorInfo["type"], monitorInfo["resolution"]); 
// 出力 :  Flat Panel 1600 x 1200

結合配列の作成に Array コンストラクタを使用するメリットはありません。たとえ Array コンストラクタや Array データ型を使用して宣言した結合配列であっても、Array.length プロパティや Array クラスのメソッドはまったく使用できないからです。Array コンストラクタはインデックス配列を作成する場合に限って使用するようお勧めします。

オブジェクトのキーを使用した結合配列

Dictionary クラスを使用すると、ストリングではなくオブジェクトをキーとする結合配列を作成できます。そのような配列は、ディクショナリ、ハッシュ、またはマップと呼ばれることがあります。たとえば、特定のコンテナとの位置関係によって Sprite オブジェクトの位置が決まるようなアプリケーションでは、個々の Sprite オブジェクトをコンテナへマップする場合に Dictionary オブジェクトを使用できます。

次のコードでは、Dictionary オブジェクトのキーとして使用する Sprite クラスのインスタンスを 3 つ作成します。各キーに対しては、GroupA または GroupB いずれかの値を格納します。格納する値には任意のデータ型を使用できますが、この例では GroupAGroupB のいずれも Object クラスのインスタンスです。次に、プロパティアクセス演算子 ([]) を使用して、各キーに対応する値にアクセスします。

import flash.display.Sprite;
import flash.utils.Dictionary;

var groupMap:Dictionary = new Dictionary();

// キーとして使用するオブジェクト
var spr1:Sprite = new Sprite();
var spr2:Sprite = new Sprite();
var spr3:Sprite = new Sprite();

// 値として使用するオブジェクト
var groupA:Object = new Object();
var groupB:Object = new Object();

// 新しいキーと値のペアをディクショナリ内に作成する
groupMap[spr1] = groupA;
groupMap[spr2] = groupB;
groupMap[spr3] = groupB;

if (groupMap[spr1] == groupA)
{
    trace("spr1 is in groupA"); 
}
if (groupMap[spr2] == groupB)
{
    trace("spr2 is in groupB"); 
}
if (groupMap[spr3] == groupB)
{
    trace("spr3 is in groupB"); 
}

オブジェクトのキーを使用した反復処理

Dictionary オブジェクトの内容に対して反復処理を実行する場合は、for..in ループまたは for each..in ループを使用できます。for..in ループはキーに基づいた反復処理に使用し、for each..in loop ループは各キーに対応する値に基づいた反復処理に使用します。

for..in ループの場合、Dictionary オブジェクト内のオブジェクトキーに直接アクセスできます。また、プロパティアクセス演算子 ([]) を使用すれば Dictionary オブジェクト内の値にアクセスできます。次のコードでは、前の例と同じ groupMap ディクショナリを使用して、for..in ループで Dictionary オブジェクトの内容を反復処理する方法を示します。

for (var key:Object in groupMap)
{
    trace(key, groupMap[key]);
}
/* 出力 :
[object Sprite] [object Object]
[object Sprite] [object Object]
[object Sprite] [object Object]
*/

for each..in ループの場合、Dictionary オブジェクト内の値に直接アクセスできます。次のコードでもやはり groupMap ディクショナリを使用して、for each..in ループで Dictionary オブジェクトの内容を反復処理する方法を示します。

for each (var item:Object in groupMap)
{
    trace(item);
}
/* 出力 :
[object Object]
[object Object]
[object Object]
*/

オブジェクトキーとメモリ管理

Adobe Flash Player では、使用されなくなったメモリはガベージコレクションのシステムによって開放されます。オブジェクトはどこからも参照されなくなった時点でガベージコレクションの対象とされ、次回ガベージコレクションが実行されるとき、そのオブジェクトに使用されていたメモリが解放されます。たとえば次のコードでは、新しいオブジェクトを作成し、そのオブジェクトへの参照を myObject という変数に割り当てています。

var myObject:Object = new Object();

オブジェクトに対して何らかの参照が存在する間は、そのオブジェクトが使用しているメモリがガベージコレクションのシステムによって解放されることはありません。myObject の値が別のオブジェクトを参照するように変更されるか、または null に設定されると、それまで参照先となっていたオブジェクトはガベージコレクションの対象とされます (そのオブジェクトに対する参照が他に存在しない場合)。

この myObject を Dictionary オブジェクトのキーとして使用すると、参照先オブジェクトに対する参照がもう 1 つ作成されます。たとえば次のコードでは、1 つのオブジェクトに対して 2 つの参照、つまり myObject 変数と、myMap オブジェクトのキーを作成しています。

import flash.utils.Dictionary;

var myObject:Object = new Object();
var myMap:Dictionary = new Dictionary();
myMap[myObject] = "foo";

myObject で参照しているオブジェクトをガベージコレクションに対して有効にするには、そのオブジェクトに対する参照をすべて削除する必要があります。この場合、そのためには myObject の値を変更するのに加え、myMap から myObject のキーを削除します。

myObject = null;
delete myMap[myObject];

別の方法として、Dictionary コンストラクタに対して useWeakReference パラメータを指定し、すべてのディクショナリキーを "弱参照" にすることもできます。弱参照はガベージコレクションのシステムで無視されるため、弱参照による参照しか受けていないオブジェクトはガベージコレクションの対象となります。たとえば次のコードでは、myMap 内の myObject キーを削除しなくても、該当するオブジェクトをガベージコレクションの対象とすることができます。

import flash.utils.Dictionary;

var myObject:Object = new Object();
var myMap:Dictionary = new Dictionary(true);
myMap[myObject] = "foo";
myObject = null; // オブジェクトをガベージコレクションの対象とする

 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート

現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000090.html