索引数组

索引数组存储一系列经过组织的单个或多个值,其中的每个值都可以通过使用一个无符号整数值进行访问。第一个索引始终是数字 0,且添加

到数组中的每个后续元素的索引以 1 为增量递增。正如以下代码所示,可以调用 Array 类构造函数或使用数组文本初始化数组来创建索引数

组:

// 使用 Array 构造函数。

var myArray:Array = new Array();

myArray.push("one");

myArray.push("two");

myArray.push("three");

trace(myArray);

// 输出:one,two,three// 使用数组文本。

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"];

可以使用 Array 类的三种方法(push() unshift()和 splice())将元素插入数组。

push()方法用于在数组末尾添加一个或多个元素。换言之,使用 push()方法在数组中插入的最后一个元素将具有最大索引号。

unshift()方法用于在数组开头插入一个或多个元素,并且始终在索引号 0 处插入。

splice()方法用于在数组中的指定索引处插入任意数目的项目。

下面的示例对所有三种方法进行了说明。它创建一个名为 planets的数组,以便按照距离太阳的远近顺序存储各个行星的名称。首先,调用

push()方法以添加初始项 Mars。接着,调用 unshift()方法在数组开头插入项 Mercury。最后,调用 splice()方法在 Mercury之后和 Mars之

前插入项 Venus和 Earth。传递给 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,但它不会从数组中删除

元素。例如,下面的代码在 oceans数组的第三个元素上使用 delete运算符,但此数组的长度仍然为 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()方法按照"默认排序顺序"重新安排数组中的元素。默认排序顺序具有以下特征:

排序区分大小写,也就是说大写字符优先于小写字符。例如,字母 D 优先于字母 b。
排序按照升序进行,也就是说低位字符代码(例如 A)优先于高位字符代码(例如 B)。
排序将相同的值互邻放置,并且不区分顺序。
排序基于字符串,也就是说,在比较元素之前,先将其转换为字符串(例如,10 优先于 3,因为相对于字符串 "3"而言,字符串 "1"具有低位

字符代码)。

您也许需要不区分大小写或者按照降序对数组进行排序,或者您的数组中包含数字,从而需要按照数字顺序而非字母顺序进行排序。sort()方

法具有 options参数,可通过该参数改变默认排序顺序的各个特征。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,因为它每次对两个数组元素进行操作。排序函数的返回值指示应如何对元素排

序:

返回值 -1 表示第一个参数 a优先于第二个参数 b。
返回值 1 表示第二个参数 b优先于第一个参数 a。
返回值为 0 表示元素具有相同的排序优先级。 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 701Dante 1265Blake 1757cummings 1894Angelou 1928/

通常,sort()和 sortOn()方法用来修改数组。如果要对数组排序而又不修改现有数组,请将 Array.RETURNINDEXEDARRAY常量作为 options参

数的一部分进行传递。此选项将指示方法返回反映排序的新数组同时保留原始数组原封不动。方法返回的数组为由反映新排序顺序的索引号组

成的简单数组,不包含原始数组的任何元素。例如,如果要根据出生年份对 poets数组排序,同时不对数组进行修改,请在传递的 options参

数中包括 Array.RETURNINDEXEDARRAY常量。 以下示例将返回的索引信息存储在名为 indices的数组中,然后使用 indices数组和未修改的

poets数组按出生年份输出诗人:

var indices:Array;indices = poets.sortOn(&quot;born&quot;, Array.NUMERIC | Array.RETURNINDEXEDARRAY);

for (var i:int = 0; i &lt; indices.length; ++i){

 var index:int = indices[i];

 trace(poets[index].name, poets[index].born);

}/* 输出:Wang 701Dante 1265Blake 1757cummings 1894Angelou 1928*/

Array 类中的其余四种方法 concat(),join(),slice()和 toString()用于查询数组中的信息,而不修改数组。concat()和 slice()方法返回新

数组;而 join()和 toString()方法返回字符串。concat()方法将新数组和元素列表作为参数,并将其与现有数组结合起来创建新数组。

slice()方法具有两个名为 startIndex和 endIndex的参数,并返回一个新数组,它包含从现有数组分离出来的元素副本。分离从 startIndex

处的元素开始,到 endIndex处的前一个元素结束。值得强调的是,endIndex处的元素不包括在返回值中。以下示例通过 concat()和 slice()

方法,使用其它数组的元素创建一个新数组:

var array1:Array = [&quot;alpha&quot;, &quot;beta&quot;];

var array2:Array = array1.concat(&quot;gamma&quot;, &quot;delta&quot;);

trace(array2); // 输出:alpha,beta,gamma,deltavar

array3:Array = array1.concat(array2);

trace(array3); // 输出:alpha,beta,alpha,beta,gamma,deltavar

array4:Array = array3.slice(2,5);

trace(array4); // 输出:alpha,beta,gamma

可以使用 join()和 toString()方法查询数组,并将其内容作为字符串返回。如果 join()方法没有使用参数,则这两个方法的行为相同,它们

都返回包含数组中所有元素的列表(以逗号分隔)的字符串。与 toString()方法不同,join()方法接受名为 delimiter的参数;可以使用此参

数,选择要用作返回字符串中各个元素之间分隔符的符号。以下示例创建名为 rivers的数组,并调用 join()和 toString()以便按字符串形式

返回数组中的值。toString()方法用于返回以逗号分隔的值 (riverCSV);而 join()方法用于返回以 +字符分隔的值。

var rivers:Array = [&quot;Nile&quot;, &quot;Amazon&quot;, &quot;Yangtze&quot;, &quot;Mississippi&quot;];

var riverCSV:String = rivers.toString();

trace(riverCSV); // 输出:Nile,Amazon,Yangtze,Mississippivar

riverPSV:String = rivers.join(&quot;+&quot;);

trace(riverPSV); // 输出:Nile+Amazon+Yangtze+Mississippi

对于 join()方法,应注意的一个问题是,无论为主数组元素指定的分隔符是什么,为嵌套数组返回的值始终以逗号作为分隔符,如以下示例所

示:

var nested:Array = [&quot;b&quot;,&quot;c&quot;,&quot;d&quot;];

var letters:Array = [&quot;a&quot;,nested,&quot;e&quot;];

var joined:String = letters.join(&quot;+&quot;);

trace(joined); // 输出:a+b,c,d+e