2007年2月3日星期六

ActionScript 3 Cookbook 中文版

ActionScript 3 Cookbook 中文版

本文未经同意,谢绝转载

第一章. ActionScript 语言基础

第二章. 自定义类

第三章. 运行时环境

第四章. 数字和数学

第五章. 数组

第六章. 可视化对象列表 (目录)

第七章. 绘图和遮罩 (目录)

第八章.位图 (目录)

第八章.位图

第八章.位图


8.0.简介

8.1.创建BitmapData对象

8.2.添加位图到可视化对象列表

8.3.绘制可视化对象到位图上

8.4.载入外部图片到位图上

8.5.处理象素

8.6.创建矩形填充

8.7.创建一个充溢填充

8.8.拷贝象素

8.9.拷贝通道

8.10.创建噪波

8.11.创建布林噪波

8.12.使用阈值

8.13.在位图上应用滤镜

8.14.在两幅位图之间转换

8.15.滚动位图

2007年1月22日星期一

第五章.数组


第五章.数组



5.16.读取联合数组


5.16. 读取联合数组

问题
我要怎样遍历联合数组
解决办法
使用 for . . . in 语句
讨论

基于整形下标的数组可以通过for 语句进行循环遍历,但是,用关键字作索引的联合数组就不能这样遍历了,还好,联合数组可以通过 for . . . in 语句进行遍历访问。该语句会访问指定对象所有可用的属性,语法如下:
for (key in object) {
// Actions
}
for . . . in 语句不需要循环变量更新语句,决定循环次数的是对象的属性个数。注意这key 就是存储每个属性名称的:
var members:Object = new Object( );
members.scribe = "Franklin";
members.chairperson = "Gina";
members.treasurer = "Sindhu";

// 使用 for . . . in 语句遍历所有元素
for (var sRole:String in members) {
// 显示:
// treasurer: Sindhu
// chairperson: Gina
// scribe: Franklin
trace(sRole + ": " + members[sRole]);
}


5.15.创建联合数组


5.15. 创建联合数组

问题
我要创建用名称元素作为索引的数组
解决办法
创建联合数组
讨论

用联合数组其每个元素都有特定的含义,这一点原来的数组类型是做不到的。
var aMembers:Array = new Array("Franklin", "Gina", "Sindhu");
联合数组在其他的语言叫做哈希表,在 ActionScript 里它就是Object 类的一个实例,联合数组使用名称元素来代替数字下标,该名称也被称为关键字或属性,说关键字更好理解些,它关联了元素值,两者一一对应。
创建联合数组不是用Array 类而是Object类创建的,它就是 Object 类的一个实例,理论上 Object 类是任何类的基类。所有的对象都能作为联合数组,但是除非有特殊需要,最好还是用 Object 类创建。
用{ } ,而且用逗号分开每个键值对,键值对之间用:,像下面:
var memebers:Object = {scribe: "Franklin",
chairperson: "Gina",
treasurer: "Sindhu"};
也可以像下面那样创建联合数组:
var members:Object = new Object( );
members.scribe = "Franklin";
members.chairperson = "Gina";
members.treasurer = "Sindhu";
有两种方法访问联合数组内容,一种是通过访问属性名称(关键字):
trace(members.scribe); // 显示: Franklin
另一种就像数组那样,把关键字作为下标来访问,用[ ] 符号:
trace(members["scribe"]); // 显示: Franklin
这种方式更加灵活,可以在数组中进行遍历,对于动态生成的关键值和内容这种访问方式是最好的,例如:
var members:Object = new Object();
members.councilperson1 = "Beatrice";
members.councilperson2 = "Danny";
members.councilperson3 = "Vladamir";
for (var i:int = 1; i <= 3; i++) {
trace(members["councilperson" + i];
}

数组访问方式在循环语句里经常用到:
var members:Object = new Object( );
members["councilperson"] = "Ruthie";
trace(members.councilperson); // 显示 Ruthie
members.councilperson = "Rebecca";
trace(members["councilperson"]); // 显示: Rebecca


5.14.比较数组


5.14. 比较数组

问题
我该怎么知道两个数组是否相等呢
解决办法
循环数组,一一比较对应位置的每个元素
讨论

因为数组是引用类型,使用=操作符只能对比引用是否指向同一内存空间,如:
var letters:Array = ["a", "b", "c", "d"];
var lettersPointer:Array = letters;
trace(letters == lettersPointer); // 显示: true
但是如果数组内容相同,但是在不同的内存空间,=操作就会返回false:
var letters1:Array = ["a", "b", "c", "d"];
var letters2:Array = ["a", "b", "c", "d"];
trace(letters1 == letters2]; // 显示: false
因此,比较数组应该比较数组的每个元素是否相等:
var equivalent:Boolean = true;
for(var i:int = 0; i < letters1.length; i++) {
if(letters1[i] != letters2[i]) {
equivalent = false;
break;
}
}
trace(equivalent); // 显示: true
另外还可以用ArrayUtilities.equals( ) 方法,该方法需要两个参数:两个数组引用,返回布尔值说明是否相等:
var letters1:Array = ["a", "b", "c", "d"];
var letters2:Array = ["a", "b", "c", "d"];
trace(ArrayUtilities.equals(letters1, letters2));
// 显示: true
默认,两个不同排列的数组是不相等的,除非提供第3个参数为true表示忽略数组排列顺序:
var letters1:Array = ["a", "b", "c", "d"];
var letters2:Array = ["b", "a", "d", "c"];
trace(ArrayUtilities.equals(letters1, letters2));
// 显示: false
trace(ArrayUtilities.equals(letters1, letters2, true));
// 显示: true
equals( ) 方法用起来很简单,下面是它的代码:
public static function equals(arrayA:Array,
arrayB:Array,
bNotOrdered:Boolean):Boolean {

// 如果两个数组长度不同
if(arrayA.length != arrayB.length) {
return false;
}

// 创建拷贝,不影响原数组
var arrayACopy:Array = arrayA.concat( );
var arrayBCopy:Array = arrayB.concat( );

// 如果忽略排列顺序
if(bNotOrdered) {
arrayACopy.sort( );
arrayBCopy.sort( );
}

// 循环比较
// 如果不匹配,删除拷贝,返回false
for(var i:int = 0; i < arrayACopy.length; i++) {
if(arrayACopy[i] != arrayBCopy[i]) {
delete arrayACopy;
delete arrayBCopy;
return false;
}
}

// 否则相等,删除数组,返回true
delete arrayACopy;
delete arrayBCopy;
return true;
}


5.13.取得数组元素的最大值和最小值


5.13. 取得数组元素的最大值和最小值

问题
我要获取数字数组的最大和最小元素
解决办法
经过数字排序,然后读取数组的第一个和最后一个元素
讨论

要想快速的取得最大值和最小值,先进行排序,看下面:
var scores:Array = [10, 4, 15, 8];
scores.sort(Array.NUMERIC);
trace("Minimum: " + scores[0]);
trace("Maximum: " + scores[scores.length - 1]);
如果不破坏原有数组顺序,可先复制数组:
也可使用 ArrayUtilities.min( )ArrayUtilities.max( ) 方法。


5.12.数组元素的随机排序


5.12. 数组元素的随机排序

问题
我要打乱数组元素的顺序
解决办法
使用 sort( ) 方法和自定义比较函数返回随机的正数或负数
讨论

很多情况我们需要得到一个随机排列的数组,比如有个游戏需要产生随机的字母。
有很多种方法达到这个目的,但是最简单的办法就是创建自定义比较函数,返回随机的正数或负数,把该函数引用传递给sort( ) 方法:
下面的比较函数就能达到目的:
function randomSort(elementA:Object, elementB:Object):Number {
return Math.random( ) - .5
}
Math.random( ) 返回0.0 到 1.0. 减去0.5 ,正好有一半的几率是负数,一半为正数,因此这个数组经过随机排序
看下面的随机排序例子:
var numbers:Array = new Array( );
for(var i:int=0;i<20;i++) {
numbers[i] = i;
}
numbers.sort(randomSort);
for(var i:int=0;i<numbers.length;i++) {
trace(numbers[i]);
}


5.11.实现自定义排序


5.11. 实现自定义排序

问题
我要自定义数组排序
解决办法
把自定义比较的函数引用传递给sort( ) 方法
讨论

如果要自定义排序,可用sort( ) 方法和自定义比较函数。sort( ) 方法重复调用比较函数对两个数组元素进行比较,比较函数接受两个参数即数组元素(我们称为a和b),根据具体的排序方式返回正数,负数或0。如果返回负数,a排在b前,如果返回0,位置不变,如果返回正数,a排在b后,直到所有元素对比完毕。
下面有个例子对字符串数组进行自定义排序,比如是一个歌曲名数组,在排序时忽略字符串中含有的"The" 字母,首先看看默认的排序:
var bands:Array = ["The Clash",
"The Who",
"Led Zeppelin",
"The Beatles",
"Aerosmith",
"Cream"];
bands.sort( );
for(var i:int = 0; i < bands.length; i++) {
trace(bands[i]);
/* 输出:
Aerosmith
Cream
Led Zeppelin
The Beatles
The Clash
The Who
*/
}
给 sort( ) 方法传递bandNameSort 比较函数:
var bands:Array = ["The Clash",
"The Who",
"Led Zeppelin",
"The Beatles",
"Aerosmith",
"Cream"];
bands.sort(bandNameSort);
for(var i:int = 0; i < bands.length; i++) {
trace(bands[i]);
/*输出
Aerosmith
The Beatles
The Clash
Cream
Led Zeppelin
The Who
*/
}

function bandNameSort(band1:String, band2:String):int
{
band1 = band1.toLowerCase( );
band2 = band2.toLowerCase( );
if(band1.substr(0, 4) == "the ") {
band1 = band1.substr(4);
}
if(band2.substr(0, 4) == "the ") {
band2 = band2.substr(4);
}
if(band1 < band2) {
return -1;
}
else {
return 1;
}
}
bandNameSort( ) 函数把字符串元素转换为小写,然后检测是否含有"The ",如果有则剪切掉,取剩余字符串进行比较


5.10.数组排序


5.10. 数组排序

问题
我要进行数组排序
解决办法
使用 sort( ) 方法,对于对象数组可以用 sortOn( ) 方法
讨论

使用 sort( ) 方法就可以对数组进行排序,没有参数是进行升序排序,对于字符内容采用 Unicode 编码排序
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
words.sort( );
trace(words); // 显示: aardvark,jargon,relative,tricycle
如果要进行降序排序,需要传递参数Array.DESCENDING 常量:
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
words.sort(Array.DESCENDING);
trace(words); // 显示: tricycle,relative,jargon,aardvark
上面的例子没有考虑大小写问题,比如:
var words:Array = ["Tricycle", "relative", "aardvark", "jargon"];
words.sort( );
trace(words); // 显示: Tricycle,aardvark,jargon,relative
使用Array.CASEINSENSITIVE 常量忽略大小写进行排序:
var words:Array = ["Tricycle", "relative", "aardvark", "jargon"];
words.sort(Array.CASEINSENSITIVE);
trace(words); // 显示 aardvark,jargon,relative,Tricycle
如果对数字内容的数组排序,则根据第一个数字的ASCII 排序:
var scores:Array = [10, 2, 14, 5, 8, 20, 19, 6];
scores.sort( );
trace(scores); // 显示: 10,14,19,2,20,5,6,8
使用 Array.NUMERIC 常量才能正常对数字排序:
var scores:Array = [10, 2, 14, 5, 8, 20, 19, 6];
scores.sort(Array.NUMERIC);
trace(scores); // 显示:2,5,6,8,10,14,19,20
还有两个常量Array.UNIQUESORTarray.RETURNINDEXEDARRAY. ,如果你只是对含有唯一元素的数组排序就可以用Array.UNIQUESORT ,Flash只会对这样的数组排序,不满足条件 sort( ) 返回0,且不进行排序:
var ranking:Array = [2,5,6,3,1,1,4,8,7,10,9];
var sortedRanking:Object = ranking.sort(Array.UNIQUESORT);
trace(sortedRanking); // 显示: 0
trace(ranking); // 显示:2,5,6,3,1,1,4,8,7,10,9
Array.RETURNINDEXEDARRAY 得到排序后数组元素的下标顺序,但不改变原始数组:
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
var indices:Array = words.sort(Array.RETURNINDEXEDARRAY);
trace(words); // 显示: tricycle,relative,aardvark,jargon
trace(indices); // 显示: 2,3,1,0
for(var i:int = 0; i < words.length; i++) {
/* 显示
aardvark
jargon
relative
tricycle
*/
trace(words[indices[i]]);
}
可以用操作符(|)联合使用这些常量:
var words:Array = ["Tricycle", "relative", "aardvark", "jargon"];
words.sort(Array.CASEINSENSITIVE | Array.DESCENDING);
trace(words); // 显示: Tricycle,relative,jargon,aardvark
有时候你想反转数组该怎么办呢?sort( ) 方法并没这功能,这是可以用 reverse( ) 方法:
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
words.reverse( );
trace(words); // 显示: jargon,aardvark,relative,tricycle
上面的部分讨论了怎么对字符串和数字进行排序,对于对象数组可用 sortOn( ) 方法,该方法需要一个字符串参数指定名称属性对其排序:
var cars:Array = new Array();
cars.push({make: "Honda", year: 1997, color: "maroon"});
cars.push({make: "Chrysler", year: 2000, color: "beige"});
cars.push({make: "Mercedes", year: 1985, color: "blue"});
cars.push({make: "Fiat", year: 1983, color: "gray"});
// 对 year 属性进行排序 cars.sortOn("year"):
for (var i:int = 0; i < cars.length; i++) {
/* 显示:
gray 1983 Fiat
blue 1985 Mercedes
maroon 1997 Honda
beige 2000 Chrysler
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}
sortOn( ) 方法也可以一次对多个字段进行排序,看下面的代码:
var cars:Array = new Array( );
cars.push({make: "Honda", year: 1997, color: "maroon"});
cars.push({make: "Chrysler", year: 2000, color: "beige"});
cars.push({make: "Mercedes", year: 1985, color: "blue"});
cars.push({make: "Fiat", year: 1983, color: "gray"});
cars.push({make: "Honda", year: 1992, color: "silver"});
cars.push({make: "Chrysler", year: 1968, color: "gold"});
cars.push({make: "Mercedes", year: 1975, color: "green"});
cars.push({make: "Fiat", year: 1983, color: "black"});
cars.push({make: "Honda", year: 2001, color: "blue"});
cars.push({make: "Chrysler", year: 2004, color: "orange"});
cars.push({make: "Mercedes", year: 2000, color: "white"});
cars.push({make: "Fiat", year: 1975, color: "yellow"});
// 对两个字段排序
cars.sortOn(["year", "make"]);
for (var i:int = 0; i < cars.length; i++) {
/* 显示:
gold 1968 Chrysler
yellow 1975 Fiat
green 1975 Mercedes
black 1983 Fiat
gray 1983 Fiat
blue 1985 Mercedes
silver 1992 Honda
maroon 1997 Honda
beige 2000 Chrysler
white 2000 Mercedes
blue 2001 Honda
orange 2004 Chrysler
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}
下面的例子,先对 make, 再对year排序:
cars.sortOn(["make", "year"]);

for (var i:int = 0; i < cars.length; i++) {
/* 显示:
gold 1968 Chrysler
beige 2000 Chrysler
orange 2004 Chrysler
yellow 1975 Fiat
black 1983 Fiat
gray 1983 Fiat
silver 1992 Honda
maroon 1997 Honda
blue 2001 Honda
green 1975 Mercedes
blue 1985 Mercedes
white 2000 Mercedes
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}
sortOn( ) 方法也可用那些数组常量完成降序,忽略大小写等排序:
cars.sortOn("year", Array.DESCENDING);

for (var i:int = 0; i < cars.length; i++) {
/* 显示:
beige 2000 Chrysler
maroon 1997 Honda
blue 1985 Mercedes
gray 1983 Fiat
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}

5.9.存储多维数据


5.9. 存储多维数据

问题
我要怎样存储多组相关的数据
解决办法
使用多维数组存储
讨论

除了一维数组,还可以创建多维数组,比如 beginGradientFill() 方法(在第7章讨论)使用三个平行数组表示colors, alphas, 和ratios ,每个数组都有相同的下标。
创建平行数组,然后操作同一下标的元素,使用平行数组,很容易访问同一下标的相关元素,比如:
var colors:Array = ["maroon", "beige", "blue", "gray"];
var years:Array = [1997, 2000, 1985, 1983];
var makes:Array = ["Honda", "Chrysler", "Mercedes", "Fiat"];

// 循环这些数组,因此数组的长度相同,可以用任何一个数组的length属性,下面的例子使用了 //makes.length.
for (var i:int = 0; i < makes.length; i++) {
trace("A " + colors[i] + " " +
years[i] + " " +
makes[i]);
// 显示:
// A maroon 1997 Honda
// A beige 2000 Chrysler
// A blue 1985 Mercedes
// A gray 1983 Fiat
}
需要注意的是,如果改变了数组长度,必须同时修改其他数组。
另一种方法就是创建多维数组,它是数组的数组:
// 创建数组 cars,然后用数组组装填充,每个元素都是数组包含3个元素 (color, year, make).
var cars:Array = new Array();
cars.push(["maroon", 1997, "Honda"]);
cars.push(["beige", 2000, "Chrysler"]);
cars.push(["blue", 1985, "Mercedes"]);
cars.push(["gray", 1983, "Fiat"]);
// 循环遍历数组
for (var i:int = 0; i < cars.length; i++) {
// 显示:
// A maroon 1997 Honda
// A beige 2000 Chrysler
// A blue 1985 Mercedes
// A gray 1983 Fiat
TRace("A " + cars[i][0] + " " +
cars[i][1] + " " +
cars[i][2]);
}

下面的代码用二重循环遍历二维数组:
for (var i:int = 0; i < cars.length; i++) {
for (var j:int = 0; j < cars[i].length; j++) {
TRace("Element [" + i + "][" + j + "] contains: " +
cars[i][j]);
}
}

从上面的例子来看,很难区别cars[i][0] 和 cars[i][j]。但如果任何数组的长度发生变化这时cars[i][0]这种表示就很被动,需要修改代码才行。
另外对象数组的使用也很类似,只是多了个名称属性。对象数组用名称属性代替数字下标来索引元素:
// 创建数组cars,填充对象
// 每个对象有个make 属性,year 属性和 color 属性
var cars:Array = new Array();
cars.push({make: "Honda", year: 1997, color: "maroon"});
cars.push({make: "Chrysler", year: 2000, color: "beige"});
cars.push({make: "Mercedes", year: 1985, color: "blue"});
cars.push({make: "Fiat", year: 1983, color: "gray"});


// 遍历数组
for (var i:int = 0; i < cars.length; i++) {
trace("A " + cars[i].color + " " +
cars[i].year + " " +
cars[i].make);
}


2007年1月21日星期日

5.8.创建数组的拷贝


5.8. 创建数组的拷贝

问题
我要复制一份数组,内容完全一样,只是不同的引用
解决办法
使用 concat( ) 方法或 slice( ) 方法,另外还可以使用ArrayUtilities.duplicate( ) 方法,duplicate( ) 方法可以创建递归复制
讨论

因为数组是复合类型,因此它的比较和复制都和基本类型不同。一个变量指向数组但是实际上它并不包含数组数据,它只是指向内存中存放数组数据的位置。从优化的角度考虑,基本类型的占用空间往往很小,但是符合类型如数组可以变得很大,如果我们在日常操作中经常复制整个数组是非常不明智的,因此当你要复制数组时,ActionScript 并不是生成独立的一份拷贝,看下面的例子:
首先我们看看基本类型是怎么复制的:
// 赋值数字5给变量
var quantity:int = 5;
// 拷贝 quantity的值 给另一个变量 newQuantity.
var newQuantity:int = quantity;
// 改变 quantity的值
quantity = 29;
trace(quantity); // 显示: 29
trace(newQuantity); // 显示: 5
我们看到,两者是互不影响的,也就是说基本变量拷贝的是值
现在我们看看数组的操作,和上面的例子不同,两个变量实际上都指向了同一个数组存贮空间。当letters 变量改变数组内容时,也影响到newLetters变量:
// 赋值数组.
var letters:Array = ["a", "b", "c"];
// 拷贝 letters 到newLetters.
var newLetters:Array = letters;
// 两个数组包含相同内容
trace(letters); // 显示: "a,b,c"
trace(newLetters); // 显示: "a,b,c"
// 改变letters的值
letters = ["d", "e", "f"];
// 另一个数组也变了
trace(letters); // 显示: "d,e,f"
trace(newLetters); // 显示: "d,e,f" (而不是 "a,b,c")
其实这就像文件夹的两个快捷方式那样,两个快捷方式虽然名字不同,但是都指向同一个文件,无论哪个对文件夹操作,另一个快捷方式也发生变化。
如果真要复制数组,可以调用数组的 concat( ) 方法:
// 给数组赋值.
var letters:Array = ["a", "b", "c"];
//用concat( ) 创建新的数组
var newLetters:Array = letters.concat( );
// 两个数组内容一样
trace(letters); // 显示: "a,b,c"
trace(newLetters); // 显示: "a,b,c"
// 改变letters的值
letters = ["d", "e", "f"];
//不像上面的例子,这次两个数组内容不同了.
trace(letters); // 显示: "d,e,f"
trace(newLetters); // 显示: "a,b,c"
也可以用 slice( ) 方法代替 concat( ), 例如:
var newLetters:Array = letters.slice(0);
concat( ) 或 slice( ) 方法复制一维整型下标的数组还可以,但是如果是多维的联合数组就不行了,对于联合数组,不能使用 concat( ) 或 slice( ) 方法,对于多维数组,用 concat( ) 或 slice( ) 只能复制顶层的数组,内部的就不能复制了,看下面的代码:
var coordinates:Array = new Array( );
coordinates.push([0,1,2,3]);
coordinates.push([4,5,6,7]);
coordinates.push([8,9,10,11]);
coordinates.push([12,13,14,15]);

// 复制
var coordinatesDuplicate:Array = coordinates.concat( );

// 替换元素
coordinatesDuplicate[0][0] = 20;
trace(coordinates[0][0]); //显示: 20

// 替换顶层元素.
coordinatesDuplicate[1] = [21,22,23,24];
trace(coordinates[1]); // 显示: 4,5,6,7
上面的代码coordinates 是个二维数组,coordinatesDuplicate 是coordinates的复制。但是,虽然是复制,有些元素仍然引用了原始数组元素,这就意味你改变了一个,会影响另一个数组的内容。实际上从上面的代码可以看出,只复制了顶层的数组,这一部分是互不关联的。
要想完全的复制数组,需要使用递归。ArrayUtilities.duplicate( ) 方法就是这样的做法,默认下它也只复制一层数组,当第2个参数设为true时则是递归复制:
// 创建二维数组
var coordinates:Array = new Array( );
for(var i:int = 0; i < 4; i++) {
coordinates[i] = new Array( );
for(var j:int = 0; j < 4; j++) {
coordinates[i].push(String(i) + "," + String(j));
}
}

// 复制coordinates.
var newCoordinates:Array = ArrayUtilities.duplicate(coordinates, true) as Array;
// 替换
newCoordinates[0][0] = "a";
// 使用toString() 方法输出
trace(ArrayUtilities.toString(coordinates));
trace(ArrayUtilities.toString(newCoordinates));
下面的例子演示用 duplicate( ) 方法复制联合数组:
var coordinatesMap:Object = new Object( );
coordinatesMap.a = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.b = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.c = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
coordinatesMap.d = [{a: 1},{b: 2}, {c: 3}, {d: 4}];
var newCoordinatesMap:Object = ArrayUtilities.duplicate(coordinatesMap, true);
newCoordinatesMap.a[0] = {r: 5};
trace(ArrayUtilities.toString(coordinatesMap));
trace(ArrayUtilities.toString(newCoordinatesMap));
两个例子可以看到,复制的数组改变不会影响原始数组。


5.7.转换数组为字符串


5.7. 转换数组为字符串

问题
我要把数组转换为字符串
解决办法
使用 join( ) 方法
讨论

ActionScript 提供内建的方法 join( ) 可以快速把数组转换为字符串(数组中的元素不管什么类型都将转换为字符串),该方法接受个参数作为分隔符:
var letters:Array = ["a", "b", "c"];
trace(letters.join("|")); // 显示: a|b|c
如果不指定分隔符,默认为逗号:
var letters:Array = ["a", "b", "c"];
trace(letters.join()); // 显示: a,b,c


当 join( ) 的分隔符为逗号,其效果和toString( ) 一样。实际上当我们直接输出数组时系统就是调用toString( ) 方法进行转换的,例如:
var letters:Array = ["a", "b", "c"];
trace(letters); // 显示: a,b,c


5.6.转换字符串为数组


5.6. 转换字符串为数组

问题
我有一堆字符串,想把它转换为数组。
解决办法
使用String.split( ) 方法
讨论

String 类的split( ) 方法把字符串转换为数组,但前提是字符串中含有统一的分割符,比如 Susan,Robert,Paula 字符串分割符为逗号
split( ) 方法接受两个参数:
分割符
用分割符来分割字符串,如果没定义,则把整个字符串作为数组的第一个元素
数量
分割出的最大元素个数,如果没定义,则全部放入数组。
可以使用空格符作为分割符:
var list:String = "Peter Piper picked a peck of pickled peppers";
var words:Array = list.split(" ");
split( ) 方法在用URLLoader 对象读取数据时经常用到,比如你接受服务器的一些姓名字符串:
names=Michael,Peter,Linda,Gerome,Catherine
这是用split( ) 方法转换为数组:
// URLLoader 读取数据
var namesData:String = _loader.data;
var names:Array = namesData.split(",");


5.5.在数组中间插入元素


5.5. 在数组中间插入元素

问题
我要在数组中间插入元素u
解决办法
使用splice( ) 方法
讨论

splice( ) 方法不仅可以删除元素,也可以插入元素,插入的元素放到第2个参数之后,当第2个参数为0代表插入元素:
var letters:Array = ["a", "b", "c", "d"];
//插入三个元素,起始位置为1
letters.splice(1, 0, "r", "s", "t");

// letters 现在包含的元素有:
// "a", "r", "s", "t", "b", "c", "d".
for (var i:int = 0; i < letters.length; i++) {
trace(letters[i]);
}

你也可以删除和插入同时执行:
var letters:Array = ["a", "b", "c", "d"];
//删除2个,插入3个
letters.splice(1, 2, "r", "s", "t");
// myArray 现在的元素
// "a", "r", "s", "t", and "d".
for (var i:int = 0; i < letters.length; i++) {
trace(letters[i]);
}


5.4.删除数组元素


5.4. 删除数组元素

问题
我要删除一个或多个数组元素,或移动数组元素
解决办法
splice( ) 方法删除指定位置的元素,pop( ) 删除尾部元素,shift( ) 删除首部元素
讨论

删除指定位置的元素使用splice( ) 方法,它需要两个参数:
start
开始下标
deleteCount
删除的元素个数,如果没有定义,则从起始位置到末尾全部删除:
var letters:Array = ["a", "b", "c", "d"];
//从下标1开始删除1个元素
letters.splice(1, 1);
// 显示结果,现在只剩三个
// "a", "c", 和 "d".
for (var i:int = 0; i < letters.length; i++) {
trace(letters [i]);
}
splice( ) 方法也返回一个新的包含删除的元素数组:
var letters:Array = ["a", "b", "c", "d"];
//删除两个元素,从0位置开始
var deleted:Array = letters.splice(0, 2);
// 显示: "a","b".
for (var i:int = 0; i < deleted.length; i++) {
trace(deleted[i]);
}
删除首部和尾部的元素可用shift( ) 和pop( ) 方法。 shift( ) 方法删除首部第一个元素,然后返回该元素,pop( ) 方法删除尾部的元素并返回该值:
var letters:Array = ["a", "b", "c", "d"];
trace(letters.shift( ));
trace(letters.pop( ));

//显示剩下的元素
for (var i = 0; i < letters.length; i++) {
trace(letters[i]);
}
在for循环里删除原始,也要修改下标值,下面的代码演示不更新下标值变量出现的情况:
var numbers:Array = new Array(4, 10);
numbers[4] = 1;
trace(numbers); // 显示: 4,10,undefined,undefined,1
for(var i:int = 0; i < numbers.length; i++) {
if(numbers[i] == undefined) {
numbers.splice(i, 1);
}
}

trace(numbers); // 显示: 4,10,undefined,1
上面的代码本来是期望上出全部undefined 元素的,结果只删除一个,调试运行,看看发生了什么:
1。前两个循环什么都没做,因为都不是undefined.
2。第三次找到 undefined 然后删除它,这时,第4个和第5个元素下移变成了第3个和第4个元素
3。下一循环检测第4个元素,也就是最后一个,这时忽略了第3个元素也就是那个undefined 元素,因此,当删除元素,应该把小标变量-1,代码应该这样:
var numbers:Array = new Array(4, 10);
numbers[4] = 1;
trace(numbers); // 显示: 4,10,undefined,undefined,1
for(var i:int = 0; i < numbers.length; i++) {
if(numbers[i] == undefined) {
numbers.splice(i, 1);
i--;
}
}

trace(numbers); // 显示: 4,10,1


5.3.搜索匹配的数组元素


5.3. 搜索匹配的数组元素

问题
我要找出指定值得数组元素
解决办法
用for 语句和break 语句就能找到匹配的元素。另外用ArrayUtilities.findMatchIndex( ), ArrayUtilities.findLastMatchIndex( ),ArrayUtilities.findMatchIndices( ) 方法
讨论

用for循环查找第一个匹配的元素后,用break立即返回,这样就实现功能了。
break应该在if语句里进行判断,是否找到匹配元素,找到则执行break推出循环,否则继续查找。
var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];

// 指定要搜索的内容
var match:String = "b";

for (var i:int = 0; i < letters.length; i++) {

// 检测当前元素是否匹配
if (letters[i] == match) {
trace("Element with index " + i +
" found to match " + match);
break;
}
}
也可以找到匹配的最后一个元素,这就需要倒序遍历数组:
var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];

var match:String = "b";
for (var i:int = letters.length - 1; i >= 0; i--) {
if (letters[i] == match) {
trace("Element with index " + i +
" found to match " + match);
break;
}
}
使用自定义类ArrayUtilities 类更简单,它在 ascb.util 包中,首先导入它:
import ascb.util.ArrayUtilities;
ArrayUtilities 类有三个方法来查找匹配的元素findMatchIndex( ), findLastMatchIndex( ), 和 findMatchIndices( )。 findMatchIndex( ) 方法至少需要两个参数:一个指向数组的引用和需要匹配的值,返回第一个匹配的元素下标,如果找不到返回-1:
var letters:Array = ["a", "b", "c", "d"];
trace(ArrayUtilities.findMatchIndex(letters, "b"));
// 显示: 1
trace(ArrayUtilities.findMatchIndex(letters, "r"));
// 显示: -1
也可以指定搜索的起始下标作为第三个参数:
var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];
trace(ArrayUtilities.findMatchIndex(letters, "a", 1));
// 显示: 4
如果第三个参数为true,则返回部分匹配的元素:
var words:Array = ["bicycle", "baseball", "mat", "board"];
trace(ArrayUtilities.findMatchIndex(words, "s", true));
// 显示: 1
如果你想部分匹配又想指定起始搜索下标,可以把起始下标作为第四个参数。
findLastMatchIndex( ) 方法返回最后一个匹配的元素下标
findMatchIndices( ) 方法返回所有匹配的元素下标数组:
var letters:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];
trace(ArrayUtilities.findMatchIndices(letters, "b"));
// 显示: 1,5
也可以设定为部分匹配,指定第三个参数为true:
var words:Array = ["bicycle", "baseball", "mat", "board"];

trace(ArrayUtilities.findMatchIndices(words, "b", true));
// 显示: 0,1,3
ArrayUtilities 方法内部也是用for循环来实现的,现在我们看看代码,下面是findMatchIndex( ) 方法的代码:



public static function findMatchIndex(array:Array, element:Object):int {
// Use a variable to determine the index
// from which to start. Use a default value of 0.
var startingIndex:int = 0;

// By default don't allow a partial match.
var partialMatch:Boolean = false;

// If the third parameter is a number,
// assign it to nStartingIndex.
// Otherwise, if the fourth parameter is a number,
// assign it to nStartingIndex instead.
if(typeof arguments[2] == "number") {
startingIndex
= arguments[2];
}

else if(typeof arguments[3] == "number") {
startingIndex
= arguments[3];
}


// If the third parameter is a Boolean value,
// assign it to partialMatch.
if(typeof arguments[2] == "boolean") {
partialMatch
= arguments[2];
}


// Assume no match is found.
var match:Boolean = false;

// Loop through each of the elements of the array
// starting at the specified starting index.
for(var i:int = startingIndex;
i
< array.length; i++) {

// Check to see if the element either matches
// or partially matches.
if(partialMatch) {
match
= (array[i].indexOf(element) != -1);
}

else {
match
= (array[i] == element);
}


// If the element matches, return the index.
if(match) {
return i;
}

}


// The following return statement is only reached
// if no match was found. In that case, return -1.
return -1;
}


public static function findMatchIndices(array:Array,
element:Object, partialMatch:Boolean
= false):Array {
var indices:Array
= new Array( );
var index:
int = findMatchIndex(array,
element,
partialMatch);
while(index != -1) {
indices.push(index);
index
= findMatchIndex(array,
element,
partialMatch,
index
+ 1);
}

return indices;
}