首页 > 技术文章 > Lua表的构造及遍历

zuibunan 2013-10-09 16:08 原文

    关于lua中的table,主要的困惑来自于table既可以当array用又可以当record用,有时候就会混淆不清。

    lua中的table貌似是用map来实现的,array是语法糖,一种特例。下面是lua中构造table的标准方法:

local numbers = {[1]=1, [2]=2, ["x"]=3, [type]=4}
numbers[1] == 1
numbers[2] == 2
numbers.x == 3
numbers[type] == 4

    构造table的标准方法是建立[key]=value的键值对,访问的时候通过table[key]的形式来获取到value。

    numbers.x 等价于 numbers[“x”]

   

    把table当array用:不用写key了,访问的时候用table[index]的形式来获取到value。注意array不连续时遍历可能出现问题

local numbers = {1, 2, 3}

numbers[5] = 5

for i=1,#numbers do
    print(numbers[i])     -- 1,2,3
end

    没有遍历到numbers[5],这是因为#numbers的值只是3,#这个操作符很奇怪,当array不连续的时候它并不能获取到正确的长度,获取到的是从1开始的连续数组的长度。所以一旦array发生了删改,就不能依赖#来获取到长度了。不过从另外一个方面讲,既然数组已经是不连续的了,那么获取table的长度也就没什么意义了。

    如果在数组不连续的状况下仍然要对数组进行顺序遍历操作,可以使用table.maxn函数,这将得到最大的整数key。

    这跟array本身的性质是一致的,想想在C++里面,如果要删除array里的一个元素,还不是得进行整块的数据移动。我想如果要把table当array用的话,就要尽量避免不要出现不连续的情况。

 

    把table当record用:numbers.x 等价于 numbers[“x”],实际上numbers.x 这种就是字符串作为key的一种语法糖。

 

    另外table可以record和array混合着用:

local numbers = {1, 2, 3, x="hello", 4, y="ha?"}

for key,value in pairs(numbers) do
    print("key: " .. tostring(key) .. ", value: " .. tostring(value))
end

-- key: 1, value: 1
-- key: 2, value: 2
-- key: 3, value: 3
-- key: 4, value: 4
-- key: y, value: ha?
-- key: x, value: hello

    这个其实也倒没什么,就是看起来畸形了点,实际中还是少用为妙。

 

 

    关于table的遍历简单说一下看法:

    如果把table当array用的并且是连续的话,使用for i=1,#numbers do的方法简洁不少。如果array不连续但是硬要遍历,那就用for i=1, table.maxn(numbers) do

    如果把table当record用的话,那就用for key,value in pairs(numbers) do。这种方法也可以遍历array,但是貌似不是顺序遍历。

    至于还有一种方法for key,value in ipairs(numbers) do,貌似效果跟#numbers是类似的,所以就没必要用它了,不方便。

 

 

 

 

    PS:再多说一下对于table进行操作的几个函数:

    table.getn() :效果和#一样

    table.foreach(key, value):效果和for key,value in pairs(numbers) do 一样

    table.foreachi(key, value): 效果和for key,value in ipairs(numbers) do 一样

    table.insert(table, pos, value): 在array中指定位置插入一个元素,类似于STL中vector的insert,把插入元素时数组的移动封装起来了,挺好用的

    table.remove : 不说了,和insert对应

    table.concat(table, sep,  start, end) : 返回一个字符串,其中包含了以sep作为分隔符的从start到end的元素

   

    具体的情况可以参考一篇文章:http://rangercyh.blog.51cto.com/1444712/1032925

推荐阅读