分享

AAuto编程【语法知识】table数据

 看见就非常 2012-08-02
【语法知识】table数据
本帖最后由 qqmmcc 于 2011-1-5 21:23 编辑

AAuto中使用table数据类型可方便的支持表驱动法编程。
table是AAuto中唯一的数据结构类型,用来构建有序或无序的集合(collection)。

一。结构
1、表结构
1.1、哈希表
无序集合又称为字典(Dictionaries)、哈希表(hashtable),映射(Map),联合内存(associative memories)联合数组(associative arrays),每个元素都是一个“键值对(key:value pairs )”。
“键”可以是字符或其他除null以外的数据类型,甚至可以在table元素中包含table,table允许嵌套。
(如:tab = {1;2;3;x=34;{y=5;6;}}

      tab[1]=1;tab[2]=2;tab[3]=3;tab["x"]=34;tab[4]["y"]=5;tab[4][1]=6
通常把“键”放在索引操作符“[]”中来索引一个元素的值,这时候键又称为“下标”或“索引”。
例如 tab["键"] tab[1]

也可以把一个符合变量命名规则的键放在成员操作符“.”后面,
例如 tab.key  tab.key2 ;

1.2、数组
table中以从1开始有序连续的数值索引存储的元素构成数组。数组在内存中的存储是有序的
如果table中的部份元素使用了数字键但是并未包含在从1开始有序连续的数值索引中、则构成稀疏数组。
在AAuto所指的数组专指有序连续数组。

二、构造表构造表
{}操作符构造新的table对象,并以分;号分隔每一个元素 (不能使用逗号代替分号)。如果成员是一个函数并以}或end结束时,可以省略分隔符。

{}操作符在表达式中只能作为赋值表达式的右值、函数参数、或被包含在另一个table构造器中,而不允许与其他操作符结合,不允许向前结合、向后结合,仅允许被括号{}[]()包含。

创建一个空的table。
days = {}

创建一个table数组。
days = { "Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"; "Saturday" }

//days[1] 的内容是 "Sunday".days[2]的内容就是"Monday"......

table元素可以使用各种数据类型的变量,甚至可以是一个表达式或者一个函数,如果我们为table中的值赋于一个键名字,则在table字典中添加一个键值对。
point = { x=100 ; y=200 }

//point.x 的值是100;point.y 的值是200,x、y是键名字

可以在一个table中同时包括“数组”、“字典”。
tab = {x=100;y=200;"Sunday"; "Monday"}

//tab.x 的值是100(即tab["x"]=100;tab.y 的值是200(tab["y"]=200
tab[1]=Sunday,tab[2]=Monday,

x=100,y=200是键值对,即字典;“Sunday","Monday"是字符数组,必须用“”


table的键名并不要求符合变量命名规则,键可以是任何除null以外的值或字符串。
但是在{}构造器中的键名必须符合变量命名规则。

在任何时候,table中不符合变量命名规则的键必须通过[]操作符访问,以下是正确的写法:
tab = { [1]=300;[2]=400;["+"]=200;[1+1]=200 }; //因为变量名不能以数字开始,更不能包含运算符。

以上的写法等价于
tab ={};
tab[1]=300;
tab[2]=400;
tab["+"]=200;
tab[1+1]=200;

我们可以把多个变量用一对花括号包含起来以转换为table数组,也可以通过table.unpack函数将table数组转换为多个变量。

tab = {"a";"abc";"abcd"} ; //多个变量创建一个table;
a,b,c = table.unpack(tab);//通过table.unpack将数组转为多个变量
tab ={ table.unpack(tab) }; //将所有返回值转换为table变量

三、在函数参数中构造表

当在函数内部有且只有一个使用{}构造器构建的table参数时,并且不包含数组元素,则{}可以省略。

例如:
func( { k = 123 ;  k2=456 }  )

可以省略{}写成如下格式:
func( k = 123 ;  k2=456 )

四、访问table成员

在访问table中的元素时,用元素的键作为下标查询元素的值,例如:

tab = {}; //用一对花括号创建一个空的table
tab["x"] = 200; //下标为字符串"x",键名为字符串"x",值为数值200。
tab[1] = "hellor world"; //下标为数字1,键索引为1,值为字符串 "hellor world"

如果“键”是一个数字索引称为“键索引”,如果键是一个字符串称为“键名

对于符合变量命名规范的键名,可以用"."成员符访问。
例如:
tab["x"] = 200; 也可以写为 tab.x = 200;

当我们将tab元素赋值为null会删除这个元素。

例如: tab.x = null; //删除tab.x

五、遍历table

遍历table列表中的全部元素

io.open(); //打开控制台窗口,用来支持print函数
tab = { a="字符串"; b=123; c="字符串2"; d=23; e=56; 78; 99; 123; 0 }
for k,v in tab  {         //k为键,v是匹配的值,在这里键值对无序的随机出现。        
io.print(k,v); //显示: 键,值 };

遍历table列表中的数组元素(有序出现)


io.open(); //打开控制台窗口,用来支持print函数
tab = { a="字符串"; b=123; c="字符串2"; d=23; e=56; 78; 99; 123; 0 }
for i=1; #tab;1 {
    io.print( i ,tab[ i ] );
}

【示例】
//打开控制台,开始我们的演示
io.open()

//table可以包含两种类型的成员。一是有序的数组,一是无序的键值对

//1、有序数组
days = { "Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"; "Saturday" }

//1.1、用#号取数组长度
io.print("数组长度",#days)

//1.2、用索引操作符[]访问成员
days[1] = "我是Sunday";
io.print( days[1] )

//1.3、用for循环遍历每个数组成员
for(i=1;#days;1){
    io.print(days[ i ] )
}

//2、无序哈希表
dic = {}

//2.1、用 table.count 号取长度(包含数组)
io.print("数组长度", table.count(dic) )

//2.2、用索引操作符[]访问成员
dic["name"] = 123;
io.print( dic["name"]  )

//2.3、可以直接用成员操作符(小圆点)访问成员
dic.name = 456;
io.print( dic.name )

//2.3、用for in 迭代遍历每个数组成员
for(k,v in dic ){
    io.print( k,v )
}



作者: look    时间: 2010-12-28 19:06
温故而知新,请问:
如果table中的部份元素使用了数字键但是并未包含在从1开始有序连续的数值索引中、则构成稀疏数组。
能举个例子吗?
作者: look    时间: 2010-12-28 19:22
发现一处错误!
/1.3、用for循环遍历每个数组成员
for (i=1;#days;1){
    io.print( days )
}
作者: ultra95    时间: 2010-12-31 22:57
本帖最后由 ultra95 于 2010-12-31 23:04 编辑

请问多维动态数组如何创建
tab={{{}}}
i,j,k
tab[j][k]=“cccc”

i,j,k只能等于1,其它数字则不行
作者: fantasynew    时间: 2010-12-31 23:39
感谢q版的辛勤工作
作者: ultra95    时间: 2011-1-1 10:56
array = table.new( 10, {} )

这个只能在开始创建吧,我的意思是根据计算的需要动态扩展大小 ,而且表中原来的数据不能破坏
作者: admin    时间: 2011-1-1 11:35
ultra95 发表于 2011-1-1 10:56
array = table.new( 10, {} )

这个只能在开始创建吧,我的意思是根据计算的需要动态扩展大小 ,而且表中 ...

AAuto的数组本就是动态的。

例如你写
tab = {“我是数组成员”}
这时候 tab[1] 是一个字符串,tab[2]是一个null空值,那么你写tab[1][2] 或者 tab[2][2] 都是没有道理的了。
因为table的成员可以是任何对象,当然也可以是table,你不能对不是table的成员或者空值来使用[]这个索引。

实际上你打开preload库,看一下table.new的源码就可以明白。
例如 tab = {}
你要写tab[2][2] 你就先要写 tab[2] = {} 然后你就可以写 tab[2][2] 了。

或者:
array = table.new( 10, {} )
array[11]= { [1] = 123; [2] = 456 }
都是可以的。



作者: admin    时间: 2011-1-1 11:37
正是因为数组是动态的,所以AAuto里并没有初始化数组大小的语句,因为没有这个需要。
table.new这是自定义的一个函数,仅仅是为了兼容其他语言的一些习惯,实际上没有必要做这个初始化。
作者: ultra95    时间: 2011-1-1 13:23
哦, 可能有点不习惯,我再试试

谢谢管理员回复,

IDE好像有点小问题,控制台程序在运行循环的情况下,按CTRL+C中止后,再点F5运行,会出现错乱 ,好像上次运行未完全退出似的
作者: admin    时间: 2011-1-1 14:23
CTRL+C 并不终止程序,只是关闭控制台

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多