美文网首页
项目问题集(二)—— Lua 中table的遍历

项目问题集(二)—— Lua 中table的遍历

作者: d546d748d718 | 来源:发表于2017-11-05 16:34 被阅读0次

    项目中有很多配置表的数据解析出来都是用表接收的,所以经常会用到对表的遍历。可是由于表中存储的数据的结构不一样,所以遍历的方式也是不一样的,有简单的表,直接存储连续数组的,也有存储list的,也有存储字典的,因为数据解析都是从C#解析过来的。  

    一:简单数字型的,这种是最简单的,内部存储的是简单的数字

    local table1 = {-1,15,10,20};

    for k,v in pairs(table1) do

           print(k,v);                                                      

    end

    for k,v in pairs (table1) do 

         print(v);

    end

    for i = 1, #table1 do 

           print(i);

    end

    打印出来的结果都是:-1,15,10,20。方法2之间带上了序号。当然数组里面也可以不是数字,其他的数据类型也是可以的,比如string类型

    当数组不连续的时候,也是可以的用上面三种方式的。

    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(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的定义有密切关系的。

    #长度

    local 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  1, 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

    相关文章

      网友评论

          本文标题:项目问题集(二)—— Lua 中table的遍历

          本文链接:https://www.haomeiwen.com/subject/kcmypxtx.html