项目中有很多配置表的数据解析出来都是用表接收的,所以经常会用到对表的遍历。可是由于表中存储的数据的结构不一样,所以遍历的方式也是不一样的,有简单的表,直接存储连续数组的,也有存储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