首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

创设数组的拷贝

2012-10-24 
创建数组的拷贝要复制一份数组,内容完全一样,只是不同的引用解决办法使用concat( ) 方法或slice( ) 方法,

创建数组的拷贝

要复制一份数组,内容完全一样,只是不同的引用
解决办法
使用concat( ) 方法或slice( ) 方法,另外还可以使用ArrayUtilities.duplicate( ) 方法,duplicate( )方法可以创建递归复制
讨论
因为数组是复合类型,因此它的比较和复制都和基本类型不同。一个变量指向数组但是实际上它并不包含数组数据,它只是指向内存中存放数组数据的位置。从优化的角度考虑,基本类型的占用空间往往很小,但是符合类型如数组可以变得很大,如果我们在日常操作中经常复制整个数组是非常不明智的,因此当你要复制数组时,ActionScript 并不是生成独立的一份拷贝,看下面的例子:

首先我们看看基本类型是怎么复制的:

-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));


两个例子可以看到,复制的数组改变不会影响原始数组。

热点排行