Flash CS3 文件 |
|||
| ActionScript 3.0 程式設計 > 處理陣列 > 索引陣列 | |||
索引陣列會儲存一系列一或多個值,這些值經過組織,可以使用無正負號的整數值加以存取。第一個索引一定是數字 0,而每個相繼新增到陣列之元素的索引則會加 1 來遞增。如下列程式碼所示,您可以呼叫 Array 類別建構函式,或以陣列常值初始化陣列,藉以建立索引陣列:
// 使用 Array 建構函式。
var myArray:Array = new Array();
myArray.push("one");
myArray.push("two");
myArray.push("three");
trace(myArray); // 輸出:one,two,three
// 使用 Array 常值。
var myArray:Array = ["one", "two", "three"];
trace(myArray); // 輸出:one,two,three
Array 類別也含有可以讓您修改索引陣列的屬性和方法。這些屬性和方法幾乎僅套用至索引陣列,而非關聯陣列。
索引陣列會使用無正負號的 32 位元整數做為索引編號。索引陣列的大小上限是 232-1 或 4,294,967,295。若試圖建立大於最大大小的陣列,將會導至執行階段錯誤。
陣列元素可以存放任何資料類型的值。ActionScript 3.0 不支援「類型陣列」的觀念,也就是說,您不能指定陣列的所有元素都屬於特定資料類型。
本節將從如何建立陣列開始,說明如何使用 Array 類別來建立並修改索引陣列。修改陣列的方法共有三種,包含如何插入元素、移除元素和排序陣列。最後一組方法會將現有陣列視為唯讀。這些方法只會查詢陣列,而不會修改現有陣列,而所有查詢方法都會傳回新的陣列。本節最後將以擴充 Array 類別的討論做為總結。
Array 建構函數有三種使用方式。第一,假設您呼叫不含引數的建構函式,會得到一個空陣列。您可以使用 Array 類別的 length 屬性來確認陣列中不包含元素。例如,下列程式碼會呼叫 Array 建構函式,並且不搭配任何引數:
var names:Array = new Array(); trace(names.length); // 輸出:0
第二,假設您使用數字做為 Array 建構函式的唯一參數,則會建立具有該長度的陣列,而且每個元素的值會設定為 undefined。引數必須是介於 0 到 4,294,967,295 之間無正負號的整數。例如,下列程式碼會呼叫 Array 建構函式,並搭配單一數值引數:
var names:Array = new Array(3); trace(names.length); // 輸出:3 trace(names[0]); // 輸出:undefined trace(names[1]); // 輸出:undefined trace(names[2]); // 輸出:undefined
第三,假設您呼叫建構函式並傳遞元素清單做為參數,則會以對應於每個參數的元素來建立陣列。下列程式碼會將三個引數傳遞給 Array 建構函式:
var names:Array = new Array("John", "Jane", "David");
trace(names.length); // 輸出:3
trace(names[0]); // 輸出:John
trace(names[1]); // 輸出:Jane
trace(names[2]); // 輸出:David
您也能夠以陣列常值或物件常值來建立陣列。陣列常值可以直接指定給陣列變數,如下列範例所示:
var names:Array = ["John", "Jane", "David"];
您可以利用 push()、unshift() 和 splice() 這三種 Array 類別方法,將元素插入陣列中。push() 方法會將一或多個元素附加到陣列結尾。換句話說,以 push() 方法插入的最後一個元素具有最高的索引編號。unshift() 方法會在陣列開頭 (索引編號一定是 0) 插入一或多個元素;而splice() 方法則會在陣列的指定索引位置插入任意數量的項目。
下列範例將示範這三種方法。建立名為 planets 的陣列,依照距離「太陽」的遠近順序儲存行星名稱。首先,呼叫 push() 方法,新增第一個項目 Mars。其次,呼叫 unshift() 方法,插入屬於陣列前方的項目 Mercury。最後,呼叫 splice() 方法將 Venus 和 Earth 項目插入 Mercury 之後、Mars 之前。傳送給 splice() 的第一個引數 (整數 1) 會指示從索引 1 開始插入;傳送給 splice() 的第二個引數 (整數 0) 則會指示不要刪除任何項目。最後,傳送給 splice() 的第三和第四個引數 Venus 和 Earth 則是要插入的項目。
var planets:Array = new Array();
planets.push("Mars"); // 陣列內容:Mars
planets.unshift("Mercury"); // 陣列內容:Mercury,Mars
planets.splice(1, 0, "Venus", "Earth");
trace(planets); // 陣列內容:Mercury,Venus,Earth,Mars
push() 和 unshift() 方法都會傳回無正負號的整數,代表修改過的陣列長度。以 splice() 方法來插入元素時會傳回空陣列,這似乎有點奇怪,但是從 splice() 方法的多功能性來看,就顯得相當合理。您不僅可以使用 splice() 方法將元素插入陣列,也能移除陣列中的元素。當您使用 splice() 方法移除元素時,會傳回包含所移除元素的陣列。
您可以使用 Array 類別的三種方法 pop()、shift() 和 splice() 移除陣列中的元素。pop() 方法會從陣列結尾移除元素。換句話說,它會移除索引編號最高的元素。shift() 方法會從陣列開頭移除元素,也就是說,它固定會移除索引編號為 0 的元素。也能用來插入元素的 splice() 方法則會從傳送至這個方法的第一個引數所指定的索引編號開始,移除任意數目的元數。
下列範例會使用這三種方法來移除陣列中的元素。建立名為 oceans 的陣列來儲存大型水域的名稱。陣列中有些名稱是湖泊的名稱,而非海洋的名稱,因此這些屬於湖泊的名稱必須加以移除。
首先使用 splice() 方法移除 Aral 和 Superior 項目,並插入 Atlantic 和 Indian 這兩個項目。傳送至 splice() 的第一個引數 (整數 2),指出這項作業是從清單的第三個項目開始,也就是位於索引 2 的項目。第二個引數 2,則指出要移除二個項目。其它引數 Atlantic 和 Indian 則是要插入索引 2 位置的值。
其次,使用 pop() 方法移除陣列中的最後一個元素 Huron。第三,使用 shift() 方法移除陣列的第一個項目 Victoria。
var oceans:Array = ["Victoria", "Pacific", "Aral", "Superior", "Indian", "Huron"]; oceans.splice(2, 2, "Arctic", "Atlantic"); // 取代 Aral 和 Superior oceans.pop(); // 移除 Huron oceans.shift(); // 移除 Victoria trace(oceans); // 輸出:Pacific,Arctic,Atlantic,Indian
pop() 和 shift() 方法都會傳回所移除的項目。傳回值的資料類型是 Object,因為陣列可以保留任何資料類型的值。splice() 方法會傳回包含所移除之值的陣列。您可以變更 oceans 陣列範例,這樣對 splice() 的呼叫就會將陣列指定給新的陣列變數,如下列範例所示:
var lakes:Array = oceans.splice(2, 2, "Arctic", "Atlantic"); trace(lakes); // 輸出:Aral,Superior
您可能會遇到針對陣列元素使用 delete 運算子的程式碼。delete 運算子會將陣列元素的值設定為 undefined,但是不會將元素從陣列中移除。例如,下列程式碼會將 delete 運算子用於 oceans 陣列的第三個元素,但是陣列的長度仍然是 5:
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Indian", "Atlantic"]; delete oceans[2]; trace(oceans); // 輸出:Arctic,Pacific,,Indian,Atlantic trace(oceans[2]); // 輸出:undefined trace(oceans.length); // 輸出:5
您可以使用陣列的 length 屬性截斷陣列。如果您將陣列的 length 屬性設定成較目前陣列更短的長度,則會截斷陣列,而這麼做會使得儲存在大於新的 length 值減 1 之索引編號的元素遭到移除。例如,假設 oceans 陣列經過排序後,所有的有效項目都移至陣列開頭,這時您就能使用 length 屬性移除陣列結尾的項目,如下列程式碼所示:
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Aral", "Superior"]; oceans.length = 2; trace(oceans); // 輸出:Arctic,Pacific
您可以使用 reverse()、sort() 及 sortOn() 這三種方法,藉由排序或反向順序排序來變更陣列的順序。這三種方法都會修改現有的陣列。reverse() 方法會變更陣列順序,使最後一個元素變成第一個元素,倒數第二個元素變成第二個元素,依此類推。sort() 方法可以讓您以各種預先定義的方式排序陣列,甚至建立自訂的排序演算法。sortOn() 方法可以讓您排序物件的索引陣列,這些物件具有一或多個共同屬性,可做為排序索引鍵。
reverse() 方法既不使用參數也不傳回值,但是可以讓您將陣列順序從目前的狀態切換為反向順序。下列範例會反轉 oceans 陣列所列的海洋順序:
var oceans:Array = ["Arctic", "Atlantic", "Indian", "Pacific"]; oceans.reverse(); trace(oceans); // 輸出:Pacific,Indian,Atlantic,Arctic
sort() 方法會使用「預設的排序順序」重新排列陣列中的元素。預設的排序順序具有下列特性:
"1" 的字元碼較字串 "3" 低)。 您也許必須忽略大小寫限制加以排序,或是以遞減順序排序,或者您要以陣列所包含的數字,而非按英文字母順序排序。只要利用 sort() 方法所具有的 options 參數,您就可以變更預設排序順序的每個特徵。這些選項是由 Array 類別中的一組靜態常數所定義,如下列清單所示:
Array.CASEINSENSITIVE:這個選項會忽略大小寫限制加以排序。例如,小寫字母 b 會排在大寫字母 D 之前。Array.DESCENDING:這會反轉預設的依遞增順序排序。例如,字母 B 會排在字母 A 之前。Array.UNIQUESORT:這會在發現兩個相同的值時,中止排序作業。Array.NUMERIC:這會進行數值排序,因此 3 會排在 10 之前。下列範例會加強說明上述幾個選項。建立名為 poets 的陣列,並以幾個不同的選項加以排序。
var poets:Array = ["Blake", "cummings", "Angelou", "Dante"]; poets.sort(); // 預設排序 trace(poets); // 輸出:Angelou,Blake,Dante,cummings poets.sort(Array.CASEINSENSITIVE); trace(poets); // 輸出:Angelou,Blake,cummings,Dante poets.sort(Array.DESCENDING); trace(poets); // 輸出:cummings,Dante,Blake,Angelou poets.sort(Array.DESCENDING | Array.CASEINSENSITIVE); // 使用兩個選項 trace(poets); // 輸出:Dante,cummings,Blake,Angelou
您也可以撰寫自己的自訂排序函數,並當做參數傳遞給 sort() 方法。例如,假設您有一份名稱清單,其中每個清單元素都包含人員的姓氏和名字,若您要依照姓氏排序清單,就必須使用自訂排序函數剖析每個元素,並在排序函數中使用姓氏。下列程式碼將說明如何以自訂函數進行上述排序,而此自訂函數是當做參數傳遞給 Array.sort() 方法:
var names:Array = new Array("John Q. Smith", "Jane Doe", "Mike Jones");
function orderLastName(a, b):int
{
var lastName:RegExp = /\b\S+$/;
var name1 = a.match(lastName);
var name2 = b.match(lastName);
if (name1 < name2)
{
return -1;
}
else if (name1 > name2)
{
return 1;
}
else
{
return 0;
}
}
trace(names); // 輸出:John Q. Smith,Jane Doe,Mike Jones
names.sort(orderLastName);
trace(names); // 輸出:Jane Doe,Mike Jones,John Q. Smith
自訂排序函數 orderLastName() 會使用規則運算式擷取每個元素的姓氏,以用於比較運算作業。針對 names 陣列呼叫 sort() 方法時,是以函數的識別名稱 orderLastName 做為唯一參數。排序函數可接受 a 和 b 參數,因為它能同時作用於兩種陣列元素。排序函數的傳回值會指出元素是以何種方式排序:
a 是在第二個參數 b 之前。 b 是在第一個參數 a 之前。 sortOn() 方法是針對具有內含物件之元素的索引陣列所設計。這些物件預期會有至少一個共同屬性,以做為排序索引鍵。將 sortOn() 方法用於其它類型的陣列時,會產生無法預期的結果。
下列範例會修改 poets 陣列,因此每個元素都會是物件而非字串。每個物件都保留了詩人的姓氏和出生年份。
var poets:Array = new Array();
poets.push({name:"Angelou", born:"1928"});
poets.push({name:"Blake", born:"1757"});
poets.push({name:"cummings", born:"1894"});
poets.push({name:"Dante", born:"1265"});
poets.push({name:"Wang", born:"701"});
您可以使用 sortOn() 方法,依照 born 屬性為陣列排序。sortOn() 方法會定義 fieldName 和 options 參數。fieldName 引數必須指定為字串。在下列範例中,會搭配兩個引數 "born" 和 Array.NUMERIC 呼叫 sortOn()。Array.NUMERIC 引數是用來確認排序是按數值順序,而非字母順序進行。即使當所有數值都具有相同數字時,這仍是相當好的作法,因為當您在稍後將具有較多或較少數字的數值加入陣列時,這種方法可以確保排序仍依照預期方式進行。
poets.sortOn("born", Array.NUMERIC);
for (var i:int = 0; i < poets.length; ++i)
{
trace(poets[i].name, poets[i].born);
}
/* 輸出:
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
一般來說,sort() 和 sortOn() 方法都會修改陣列。若您希望排序陣列但不修改現有陣列,請傳遞 Array.RETURNINDEXEDARRAY 常數做為 options 參數的一部分。這個選項會指示方法傳回能夠反應排序的新陣列,並保留原始陣列不變。方法所傳回的陣列是可以反應新排序順序的索引編號簡單陣列,其中不包含原始陣列的任何元素。例如,若要依出生年份排序 poets 陣列而不修改陣列,請將 Array.RETURNINDEXEDARRAY 常數納入要傳遞做為 options 參數之引數的一部分。
下列範例會將傳回的索引資訊儲存在名為 indices 的陣列中,並使用 indices 陣列和未修改的 poets 陣列依出生年份輸出詩人名稱:
var indices:Array;
indices = poets.sortOn("born", Array.NUMERIC | Array.RETURNINDEXEDARRAY);
for (var i:int = 0; i < indices.length; ++i)
{
var index:int = indices[i];
trace(poets[index].name, poets[index].born);
}
/* 輸出:
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
Array 類別的其它四種方法 concat()、join()、slice() 和 toString() 都會向陣列查詢資訊,但是不會修改陣列。concat() 和 slice() 方法會傳回新的陣列,而 join() 和 toString() 方法則會傳回字串。concat() 方法會採用新的陣列或元素清單做為引數,並將它合併至現有陣列以建立新的陣列。slice() 方法有兩個參數,即名符其實的 startIndex 和 endIndex,它們會傳回新的陣列,其中包含自現有陣列「分割」出來的元素副本。此分割是從 startIndex 的元素開始,並結束於 endIndex 之前的元素。在此要重複提醒的是:位於 endIndex 的元素不會包含在傳回值中。
下列範例會使用 concat() 和 slice(),利用其它陣列的元素來建立新的陣列:
var array1:Array = ["alpha", "beta"];
var array2:Array = array1.concat("gamma", "delta");
trace(array2); // 輸出:alpha,beta,gamma,delta
var array3:Array = array1.concat(array2);
trace(array3); // 輸出:alpha,beta,alpha,beta,gamma,delta
var array4:Array = array3.slice(2,5);
trace(array4); // 輸出:alpha,beta,gamma
您可以使用 join() 和 toString() 方法來查詢陣列,並傳回陣列內容做為字串。如果沒有對 join() 方法使用任何參數,這兩種方法的行為方式是相同的,亦即它們都會傳回字串,其中包含陣列內以逗點分隔的所有元素清單。join() 方法與 toString() 方法不同,前者會採用名為 delimiter 的參數,可以讓您選擇符號,以做為傳回字串中每個元素之間的分隔符號。
下列範例會建立名為 rivers 的陣列,並同時呼叫 join() 和 toString() 以字串型式傳回陣列中的值。使用 toString() 方法可傳回以逗點分隔的值 (riverCSV),而使用 join() 方法則可傳回以 + 字元分隔的值。
var rivers:Array = ["Nile", "Amazon", "Yangtze", "Mississippi"];
var riverCSV:String = rivers.toString();
trace(riverCSV); // 輸出:Nile,Amazon,Yangtze,Mississippi
var riverPSV:String = rivers.join("+");
trace(riverPSV); // 輸出:Nile+Amazon+Yangtze+Mississippi
有關 join() 方法要注意的一點是,不管您為主要陣列元素指定了何種分隔符號,所有巢狀陣列一律都會傳回以逗點分隔的值,如下列範例所示:
var nested:Array = ["b","c","d"];
var letters:Array = ["a",nested,"e"];
var joined:String = letters.join("+");
trace(joined); // 輸出:a+b,c,d+e
Flash CS3
目前頁面: http://livedocs.adobe.com/flash/9.0_tw/main/00000089.html