项目中有很多配置表的数据解析出来都是用表接收的,所以经常会用到对表的遍历。可是由于表中存储的数据的结构不一样,所以遍历的方式也是不一样的,有简单的表,直接存储连续数组的,也有存储list的,也有存储字典的,因为数据解析都是从C#解析过来的
一:简单数字型的,这种是最简单的,内部存储的是简单的数字
local table1 = {-1,15,10,20};
for k,v in ipairs(table1) do
print(k,v);
end
for k,v in pairs (table1) do
print(v);
end
for i = 1, #table1 do
print(table1[i]);
end
打印出来的结果都是:-1,15,10,20。方法1上带上了序号。当然数组里面也可以不是数字,其他的数据类型也是可以的,比如字符串类型
当数组不连续的时候,也是可以的用上面三种方式的。
local table1 = {-1,15,10,20};
table1[6] = "laowang";
for k,v in ipairs(table1) do
print(k,v);
end
for k,v in pairs(table1) do
print(k,v);
end
for i-1, #table1 do
print(table1[i]);
end
打印出来的结果是:
-1,15,10,20
-1,15,10,20,laowang
-1,15,10,20,nil,老王
很明显也是可以遍历的。ipairs遇到nil结束了遍历。
二:键值对类型的table
键值对类型的table只用使用table自带的迭代器(pairs和ipairs)来进行遍历,因为此时的table不能通过#来获取长度
local table2 = {key1 = 1, b=2, C = 4};
for k,v in pairs(table2) do
print(k,v);
end
打印的结果是:key1 1, b 2,C 4; 但是没有办法通过#table2来获取table2的长度
三:userData类型的数据就直接按照类型来遍历即可
因为工作中经常遇到数据解析,解析后的数据可能是list,也可能是字典。当用lua来遍历这种类型的数据时,就直接用list和字典的遍历方式遍历即可。
四:pais,ipairs和#的区别
这几个关键字的区别是和table的定义有密切关系的。
#长度
ocal table1 = {0,2,3,4};
local table2 = {[1] = 0, [2]=2,[3] = 3,[4] = 4};
local table3 = {[0] = 0, [1]=2, [2] = 3, [3]=4};
print(table1[0]);
print(table1[1]);
print(table2[0]);
print(table2[1]);
print(table3[0].." "..table3[1]);
打印的结果是:nil 0, nil 0,0 2;从这一点可以很明确的看出来,默认像数组一样定义出来的table是从索引为1开始的。但是和数组不一样的一点时,table中索引是可以自己定义的,可以从任意数字开始,而且索引也是可以任意的
例如:local table4 = {[2]=3, [5]=4, [10]=0, [-1]=2};
这样定义的话,table是没有0,1索引的,是从2号索引开始的。同时是有-1索引值的。
对上面4个table做#运算会发现,table1的长度是4,table2是4,table3是3,table4是0。再定义下面的table5,获取其长度
local table5={[2]=2, [3]=3, [4]=4};
获取的长度是0。从这一点可以看出,#符号是和索引1相关的,利用#求一个的长度时,lua会遍历这个表,从中查找索引1,如果没有1号索引,就输出0,如果有1号索引,就向后依次按照索引递增查找,直到索引递增中断
例如:local table6={[0]=0, [1]=1, [2]=2, [5] = 5};
通过#获取的长度只是2,因为没有3号索引,因此lua就中断了查找行为,输出了2。
ipairs遍历
是根据key值的大小顺序来遍历的,而且,key值一定要是连续的,遇到不连续的地方,就会结束遍历。
例如:local table1 = {[1]=1, [2]=2, [3]=3, [5]=4};
local table2 = {[0]=1, [1]=2, [2]=3, [3]=4};
local table3 = {[2]=2, [3]=3, [4]=4};
for k,v in ipairs(table1) do
print(k,v);
end
for k,v in ipairs(table2) do
print(k,v);
end
for k,v in ipairs(table3) do
print(k,v);
end
打印的结果是:1 1, 2 2, 3 3和 1 2, 2 3, 3 4。第三个没有输出结果。因此可以的到这样的结论,ipairs是只遍历table中,索引从1开始,以1递增的部分。遇到索引中断,就结束执行。这一点和#有点相像。
pairs遍历
pairs遍历是唯一的可以遍历table中所有元素的方法,不过也有缺点,就是遍历的顺序不是按照key的定义顺序来的,而是按照key只的哈希值来遍历的。当然,如果遍历的是简单的数组样式的table,顺序是不会乱的,但是如果人为定义了key值,那么顺序将会有所不同。
问题
上面说过,#的遍历是从1开始,遇到不连续就会终止,不过在某些情况下,也会有例外:
例如:local table1={[1]=1, [2]=2, [3]=3, [5]=5};
lcoal tabe2 = {[1]=1, [2]=2, [4] =4, [5] = 5};
上面两个table的#运算结果分别是3和5。这种情况似乎是和里面key值有关系,当key值满足2的指数时,就可以直接遍历,并且和偶数也有关系,情况比较复杂。
http://rangercyh.blog.51cto.com/all/1444712/9