`

创建数组的拷贝

    博客分类:
  • flex
阅读更多

要复制一份数组,内容完全一样,只是不同的引用
解决办法
使用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));


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

分享到:
评论

相关推荐

    关于数组创建以及拷贝时的内存分配

    接下来,我们讨论数组拷贝。拷贝一个数组,尤其是大数组时,会涉及到两种主要策略:浅拷贝和深拷贝。浅拷贝仅仅复制了数组的引用,这意味着两个数组都指向同一块内存。因此,改变其中一个数组会影响到另一个。在C++...

    dotnet 6 数组拷贝性能对比.rar

    在.NET 6中,数组拷贝是一个常见的操作,特别是在处理大量数据时。本文将深入探讨.NET 6中数组拷贝的性能对比,并将其与Java语言的相应操作进行比较。了解这些知识对于优化代码效率和提升应用程序性能至关重要。 ...

    js数组的深拷贝

    深拷贝与浅拷贝不同,浅拷贝只是复制引用,而深拷贝会创建一个新的对象,包含原始数组的所有元素,并逐个复制每个元素的值,包括对象和数组。这样,原始数组的改变不会影响到深拷贝后的数组。 深拷贝的方法有很多种...

    Swift视频教程:集合类型 创建数组及初始化

    3. 数组的拷贝:使用`copy()`方法创建数组副本,避免引用同一内存地址。 六、多维数组 Swift支持多维数组,例如二维数组可以表示表格数据。创建二维数组的方式有多种,如: ```swift var matrix = [[1, 2], [3, 4]]...

    javascript数组操作(创建、元素删除、数组的拷贝)

    - `slice(0)` 或 `concat()`:这两个方法可以用来创建数组的浅拷贝,生成的新数组与原数组独立。 7. **数组元素的排序**: - `reverse()`:反转数组元素的顺序。 - `sort()`:对数组元素进行排序,默认按字母...

    JS实现数组深拷贝的方法分析

    在JavaScript中,数组的深拷贝是指创建一个新数组,该数组包含原始数组的所有元素,并且这些元素如果是对象或数组,也会被递归地深度复制。这样,原始数组的任何修改都不会影响到深拷贝后的数组。以下是对JS实现数组...

    实现数组复制常用的5种方式及组合类的深复制(深拷贝)

    这个方法用于复制数组的一部分,创建新的数组包含原数组的指定范围。与`Arrays.copyOf()`类似,效率也较高。 ```java arr2 = Arrays.copyOfRange(arr, 0, length); ``` 对于组合类的深复制,如果类中包含其他可变...

    vue 使用lodash实现对象数组深拷贝操作

    深拷贝是一种重要技术,用于创建一个原始对象的副本,而不会影响原始数据。本篇文章主要探讨了如何在Vue中利用lodash库实现对象数组的深拷贝。 首先,lodash是一个非常实用的JavaScript工具库,提供了大量的实用...

    python数组复制拷贝的实现方法

    ### Python 数组复制拷贝的实现方法 在Python编程中,数据结构的处理非常重要,而数组作为其中一种基本的数据类型,在各种应用场景中扮演着关键角色。对于数组的复制拷贝,掌握其正确的方法有助于避免一些常见的...

    JavaScript数组深拷贝和浅拷贝的两种方法

    以上两种方法都属于深拷贝,它们都创建了一个新的数组对象,这样在对新数组进行操作时,原始数组不会被改变。需要注意的是,`slice()` 和 `concat()` 方法仅适用于一维数组的深拷贝。如果数组中还包含了其他数组,...

    C++ 类的深拷贝

    1. **创建数组对象 v1 和 v2**: - 使用内置静态整型数组 `{1, 2, 3, 4, 5}` 构造 `v1`。 - 用户输入整型数来构造 `v2`。 2. **输出 v1 和 v2 的所有元素**。 3. **设置数组对象 v1 的指定元素**。 4. **根据数组...

    js创建数组的简单方法

    本文将详细介绍几种常见的JS创建数组的方法,以及数组的一些基本操作。 1. **数组的声明方法** - **无参数创建**:`arrayObj = new Array();` 或 `var arr1 = new Array();` 这种方式创建的是一个空数组。 - **...

    java 一维数组的创建与使用

    2. **数组拷贝**:`System.arraycopy()`方法可以用来复制数组的一部分或全部。 3. **数组比较**:虽然数组本身是对象,但比较两个数组是否相等时,需要注意的是它们的引用是否相同,而非内容是否一致。若要比较内容...

    JS 数组和对象的深拷贝操作示例

    扩展运算符可以用于创建数组的深拷贝。它的工作原理类似于`slice()`,但可以直接用于解构赋值,如`let arr1 = [...arr]`。 二、对象的深拷贝 1. 扩展运算符 (`...`) 和 `Object.assign()` 同样,扩展运算符和`...

    javascript二维数组和对象的深拷贝与浅拷贝实例分析

    2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用” JavaScript的数据类型分为原始数据类型和对象类型。二者在内存中存放的方式不同,导致了其赋值...

    java array

    本节内容包括 数组基本概念 数组的声明与创建 数组的特性 数组拷贝 命令行参数 工具类java.util.Arrays 多维数组

    java 数组 PPT

    2. 深拷贝与浅拷贝:数组拷贝有深拷贝(复制整个数组及其中的元素)和浅拷贝(只复制数组引用)之分,使用`System.arraycopy()`方法可以实现深拷贝。 3. 排序:Java的`Arrays`类提供了对数组进行排序的方法,如`...

Global site tag (gtag.js) - Google Analytics