關聯陣列

關聯陣列有時也稱為「雜湊」或「對應」,它會使用「索引鍵」而非數值索引來組織儲存的值。關聯陣列中的每個索引鍵都是唯一的字串,可用來存取儲存的值。關聯陣列是 Object 類別的實體,也就是說,每個索引鍵都會對應到一個屬性名稱。關聯陣列是索引鍵與值配對的無順序集合。程式碼不應該寄望關聯陣列的索引鍵會有一定的順序。

ActionScript 3.0 新增了名為「字典」的進階類型關聯陣列。字典是 Dictionary 類別在 flash.utils 套件中的實體,它所使用的索引鍵可以是任何資料類型,但通常是 Object 類別的實體。換句話說,字典的索引鍵不限於 String 類型的值。

本節說明如何建立使用字串做為索引鍵的關聯陣列,以及 Dictionary 類別的使用方式。

副主題

具有字串索引鍵的關鍵陣列
具有物件索引鍵的關聯陣列

具有字串索引鍵的關鍵陣列

在 ActionScript 3.0 中,可以使用兩種方式來建立關聯陣列。第一種是使用 Object 建構函式,這種方式的優點是能夠以物件常值初始化陣列。Object 類別的實體 (也稱為一般物件) 在功能上和關聯陣列完全相同。一般物件的每個屬性名稱都能當做索引鍵,可用來存取儲存的值。

下列範例會建立名為 monitorInfo 的關聯陣列,並使用物件常值來初始化包含兩個索引鍵和值配對的陣列:

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

monitorInfo["aspect ratio"] = "16:10"; // 不良格式,請勿使用空格
monitorInfo.colors = "16.7 million";
trace(monitorInfo["aspect ratio"], monitorInfo.colors);
// 輸出:16:10 16.7 million

請注意,名為 aspect ratio 的索引鍵包含空格字元。這對於方括號運算子是可行的,但要是使用點運算子,就會產生錯誤。最好是不要在索引鍵名稱中使用空格。

第二種建立關聯陣列的方式就是使用 Array 建構函式,然後再使用方括號運算子 ([]) 或點運算子 (.),將索引鍵與值配對加入陣列中。如果將關聯陣列宣告為 Array 類型,就無法使用物件常值來初始化陣列。下列範例會使用 Array 建構函式來建立名為 monitorInfo 的關聯陣列,然後將 type 索引鍵和 resolution 索引鍵,連同其各自的值一併加入該陣列中:

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 物件與特定容器的關聯,找到該物件的位置。您可以使用 Dictionary 物件,將每個 Sprite 物件對應到容器。

下列程式碼會建立 Sprite 類別的三個實體,做為 Dictionary 物件的索引值。為每個索引鍵分別指定 GroupAGroupB 的值。這些值可以是任何資料類型,但是在本範例中,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"); 
}

重複物件索引鍵

您可以使用 for..in 迴圈或 for each..in 迴圈,重複執行 Dictionary 物件的內容。for..in 迴圈可以讓您根據索引鍵重複執行,而 for each..in 迴圈則可以讓您根據與每個索引鍵相關聯的值重複執行。

您可以使用 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 物件中的索引鍵,表示您正為原始物件建立另一個參考。例如,下列程式碼會為物件建立兩個參考,它們分別是 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; // 使物件可進行記憶體回收。

Flash CS3

 

有新的意見加入至這個頁面時,傳送電子郵件給我 | 意見報告

目前頁面: http://livedocs.adobe.com/flash/9.0_tw/main/00000090.html