《AS3 Expert》_3:为什么for不能有序遍历数组的所有元素?
来源:互联网 发布:移动硬盘排名知乎 编辑:程序博客网 时间:2024/05/01 01:34
这个题目略微浅显,但却不易讲明白。如果我告诉你,我们不能以任何代码保证可以有序遍历出一个数组的所有元素,你肯定会反驳我,因为使用for明明就可以啊!但其实不是。
一、为什么for不能保证遍历所有?
代码0:复制代码代码0仅能遍历出3个元素,原因在于动态添加的元素name是在Object上添加的,因Array是动态对象所以可以这样行码,但它并不受Array管理,也并未被统计在length之中。
二、Array对象是如何设计的?
Array继承于Object,是动态对象,使用动态属性直接在Object上存储数据。当下标与元素的对应关系发生变化时,受到影响的属性名称会全部重写。Array在内部维护一个length属性,元素的改变不受制于length,length因元素而改变。(注:此观点乃sban个人推测,非官方,接爱请审慎)
据上一段,我们可以推断:
1,设有数组arr1,arr1[0]元素的属性名称为“0”,使用arr1[0]访问数组元素与使用arr1[“0”]的效果是相同的
2,对于大数组的添加元素操作,push的效率远远高于unshift
3,数组既可以使用for遍历,也可以使用for in与for each in遍历,后两者是所有Object都具有的遍历方法。
4,可以无视数组的定义长度,跳跃指定元素的下标。
让我们验证一下我们的推断:
代码1:复制代码代码2:复制代码代码3复制代码代码4:复制代码这个白痴的特性让人很失望!C语言的数组从来都是先分配大小的,不充许越界赋值。AS3的Array的length变得没有任何实际意义,它既不能限制数组元素的随意添加,也不能正确的彰显数组到底有多少元素。
三、为什么Adobe要把Array设计为动态对象?
在AS3中,其它基本数据类型如String,Number均是非动态对象,为什么Array要被设计为动态对象?Adobe为什么要充许外部代码在Array上动态创建属性?Array作为数组,竟然可以拥有自己的动态属性,貌似这是一个很不合理的设计。
作者并非在Adobe工作,并不了解如此设计的真正玄机。sban看过一份Flash Player v4 v++源码,但Array是Flash Player 9之后才出现的,里面并没有关于Array的相关代码。
sban推测正则表达式的命名组功能是促使Adobe把Array设计为动态对象的主要原因之一。
代码4:var s :String = “as expert programming by sban.“;var arr : Array = /by (?P\w+)/i.exec(s);trace(arr.name);//sbantrace(arr is Array);//true
对于正则的exec方法,如何保证在返回数组对象的同时,该对象又具有用户指定的动态属性,把Array设计为动态对象是最简洁的方法之一,并且这与AS3是一门纯面向对象语言的思想并不违悖。
四、总结
遍历一个数组有三种方法:
1,for遍历
2,for in遍历
3,for each in遍历
如果要保证有序遍历,只能使用方法一,但不能保证遍历所有;如果要保证遍历所有,可以使用方法2或3,但不能保证有序。三种方法遍历小数组的效率没有差别,遍历大数组时略有差别。
五、建议
存储无序元素集合,使用Object优于Array。
一、为什么for不能保证遍历所有?
代码0:
- var arr1 :Array = ["as3", "expert", "programming"];
- arr1.name = "sban";
- for(var j:int=0; j
- {
- trace(arr1[j]);
- }
二、Array对象是如何设计的?
Array继承于Object,是动态对象,使用动态属性直接在Object上存储数据。当下标与元素的对应关系发生变化时,受到影响的属性名称会全部重写。Array在内部维护一个length属性,元素的改变不受制于length,length因元素而改变。(注:此观点乃sban个人推测,非官方,接爱请审慎)
据上一段,我们可以推断:
1,设有数组arr1,arr1[0]元素的属性名称为“0”,使用arr1[0]访问数组元素与使用arr1[“0”]的效果是相同的
2,对于大数组的添加元素操作,push的效率远远高于unshift
3,数组既可以使用for遍历,也可以使用for in与for each in遍历,后两者是所有Object都具有的遍历方法。
4,可以无视数组的定义长度,跳跃指定元素的下标。
让我们验证一下我们的推断:
代码1:
- var arr1 :Array = ["as3", "expert", "programming"];
- trace(arr1[0], arr1["0"]);//as3 as3
- var arr1 :Array = [], arr2 :Array = [];
- var t1:Number, t2:Number;
- t1 = new Date().getTime();
- for(var j:Number=0;j<100000;j++)
- {
- arr1.push(j);
- }
- t2 = new Date().getTime();
- trace("push耗约:", t2-t1);//push耗约: 35
- t1 = new Date().getTime();
- for(var j:Number=0;j<100000;j++)//这个数值如果太大,比如5千万,你会发现你的电脑根本就无法完成它
- {
- arr2.unshift(j);
- }
- t2 = new Date().getTime();
- trace("unshift循环耗约:", t2-t1);//unshift循环耗约: 7881
- var t1:Number, t2:Number;
- var arr1 :Array = [];
- for(var j:Number=0;j<50000000;j++)//for遍历
- {
- arr1.push(j);
- }
- t1 = new Date().getTime();
- for each(var p:* in arr1)//for each in遍历
- {
- var i1:* = p;
- }
- t2 = new Date().getTime();
- trace("for each in耗约:", t2-t1);//for each in耗约: 8891
- t1 = new Date().getTime();
- for(var p:* in arr1)//for遍历
- {
- var i2:* = arr1[p];
- }
- t2 = new Date().getTime();
- trace("for in耗约:", t2-t1);//for in耗约: 9861
- t1 = new Date().getTime();
- var n:Number = arr1.length;
- for(var k:Number=0; k<n; k++)
- {
- var i3:* = arr1[k];
- }
- t2 = new Date().getTime();
- trace("for耗约:", t2-t1);//for耗约: 9720
- var arr :Array = new Array(1);
- arr['2'] = "sban";//arr[2] = "sban",使用数字与字符串作下标,效率是相同的,AS3内部会作必要的类型转化
- trace("length:", arr.length);
- for(var j:int=0; j<arr.length; j++)
- {
- trace(arr[j]);
- }
- /*
- length: 3
- undefined
- undefined
- sban
- */
三、为什么Adobe要把Array设计为动态对象?
在AS3中,其它基本数据类型如String,Number均是非动态对象,为什么Array要被设计为动态对象?Adobe为什么要充许外部代码在Array上动态创建属性?Array作为数组,竟然可以拥有自己的动态属性,貌似这是一个很不合理的设计。
作者并非在Adobe工作,并不了解如此设计的真正玄机。sban看过一份Flash Player v4 v++源码,但Array是Flash Player 9之后才出现的,里面并没有关于Array的相关代码。
sban推测正则表达式的命名组功能是促使Adobe把Array设计为动态对象的主要原因之一。
代码4:var s :String = “as expert programming by sban.“;var arr : Array = /by (?P\w+)/i.exec(s);trace(arr.name);//sbantrace(arr is Array);//true
对于正则的exec方法,如何保证在返回数组对象的同时,该对象又具有用户指定的动态属性,把Array设计为动态对象是最简洁的方法之一,并且这与AS3是一门纯面向对象语言的思想并不违悖。
四、总结
遍历一个数组有三种方法:
1,for遍历
2,for in遍历
3,for each in遍历
如果要保证有序遍历,只能使用方法一,但不能保证遍历所有;如果要保证遍历所有,可以使用方法2或3,但不能保证有序。三种方法遍历小数组的效率没有差别,遍历大数组时略有差别。
五、建议
存储无序元素集合,使用Object优于Array。
- 《AS3 Expert》_3:为什么for不能有序遍历数组的所有元素?
- [java]一次for循环实现查询有序数组中所有重复的元素
- java 为什么遍历的时候不能删除元素
- js数组循环遍历数组内所有元素的方法
- JS数组循环遍历数组内所有元素的方法
- 遍历数组的所有元素的三种方式
- JAVA “:”无法遍历数组的所有元素问题
- C++的数组元素为什么不能是引用类型
- as3遍历对象所有属性的方法
- as3遍历对象所有属性的方法
- 《As3 Expert》_1 :数组操作符的用途,如何访问不可访问的东东?
- 阿里13年研发笔试题 - 寻找有序数组中元素值等于其下标的所有元素
- matlab 条件删除某元胞元素时不能使用for,而应该使用while进行遍历所有元胞
- 求两个有序数组的共有元素
- 查找循环有序数组的元素
- 二维数组遍历求和操作:用二重循环求出二维数组b所有元素的和。
- 程序员面试题目总结--数组(一)【递归求数组所有元素和、用一个for循环打印出一个二维数组、用递归判断数组是否是递增、有序数组中删除重复元素】
- js数组循环遍历数组内所有元素
- C#查找数组中相同的项并合并
- 《疯狂的程序员》三
- CLR via C# 之旅
- Matlab.Net混编
- 一周以来工作总结--关于位图索引
- 《AS3 Expert》_3:为什么for不能有序遍历数组的所有元素?
- console.log---被我一直忽视的神器
- 《疯狂的程序员》四
- C++ 对象的内存布局
- Real-Time Transport Protocol (RTP) Parameters
- C++内存分配及变长数组的动态分配
- C++ fill() fill_n() back_inserter 简析
- 1
- Python 的 Socket 编程教程