Lua资料之table函数

本文深入探讨Lua中的表格操作,包括获取长度、连接、插入、删除、排序等关键函数的使用方法,以及LuaJIT2.1新增的table.new和table.clear函数的介绍。

◆ table.getn 获取长度
取长度操作符写作一元操作 #。字符串的长度是它的字节数(就是以一个字符一个字节计算的字符串长度)。对于常规的数组,里面从 1 到 n 放着一些非空的值的时候,它的长度就精确的为 n,即最后一个值的下标。如果数组有一个“空洞”(就是说,nil 值被夹在非空值之间),那么 #t 可能是指向任何一个是 nil 值的前一个位置的下标(就是说,任何一个 nil 值都有可能被当成数组的结束)。这也就说明对于有“空洞”的情况,table 的长度存在一定的 不可确定性。

local tblTest1 = { 1, a = 2, 3 }
print("Test1 " .. table.getn(tblTest1))
local tblTest2 = { 1, nil }
print("Test2 " .. table.getn(tblTest2))
local tblTest3 = { 1, nil, 2 }
print("Test3 " .. table.getn(tblTest3))
local tblTest4 = { 1, nil, 2, nil }
print("Test4 " .. table.getn(tblTest4))
local tblTest5 = { 1, nil, 2, nil, 3, nil }
print("Test5 " .. table.getn(tblTest5))
local tblTest6 = { 1, nil, 2, nil, 3, nil, 4, nil }
print("Test6 " .. table.getn(tblTest6))

使用 Lua 5.1 和 LuaJIT 2.1 分别执行这个用例,结果如下:

# lua test.lua
Test1 2
Test2 1
Test3 3
Test4 1
Test5 3
Test6 1
# luajit test.lua
Test1 2
Test2 1
Test3 1
Test4 1
Test5 1
Test6 1

不要在 Lua 的 table 中使用 nil 值,如果一个元素要删除,直接 remove,不要用 nil 去代
替。

◆ table.concat (table [, sep [, i [, j ] ] ])
对于元素是 string 或者 number 类型的表 table,返回 table[i]..sep..table[i+1] ···
sep..table[j] 连接成的字符串。填充字符串 sep 默认为空白字符串。起始索引位置 i 默认为1,结束索引位置 j 默认是 table 的长度。如果 i 大于 j,返回一个空字符串。

local a = {1, 3, 5, "hello" }
print(table.concat(a))              -- output: 135hello
print(table.concat(a, "|"))         -- output: 1|3|5|hello
print(table.concat(a, " ", 4, 2))   -- output:
print(table.concat(a, " ", 2, 4))   -- output: 3 5 hello

◆ table.insert (table, [pos ,] value)
在(数组型)表 table 的 pos 索引位置插入 value,其它元素向后移动到空的地方。pos 的默认值是表的长度加一,即默认是插在表的最后。

local a = {1, 8}             --a[1] = 1,a[2] = 8
table.insert(a, 1, 3)   --在表索引为1处插入3
print(a[1], a[2], a[3])
table.insert(a, 10)    --在表的最后插入10
print(a[1], a[2], a[3], a[4])
-->output
3    1    8
3    1    8    10

◆ table.maxn (table)
返回(数组型)表 table 的最大索引编号;如果此表没有正的索引编号,返回 0。
当长度省略时,此函数通常需要 O(n) 的时间复杂度来计算 table 的末尾。因此用这个函数省略索引位置的调用形式来作 table 元素的末尾追加,是高代价操作。

local a = {}
a[-1] = 10
print(table.maxn(a))
a[5] = 10
print(table.maxn(a))
-->output
0
5

此函数的行为不同于 # 运算符,因为 # 可以返回数组中任意一个 nil 空洞或最后一个 nil 之前的元素索引。当然,该函数的开销相比 # 运算符也会更大一些。

◆ table.remove (table [, pos])
在表 table 中删除索引为 pos(pos 只能是 number 型)的元素,并返回这个被删除的元素,它后面所有元素的索引值都会减一。pos 的默认值是表的长度,即默认是删除表的最后一个元素。

local a = { 1, 2, 3, 4}
print(table.remove(a, 1)) --删除速索引为1的元素
print(a[1], a[2], a[3], a[4])
print(table.remove(a))   --删除最后一个元素
print(a[1], a[2], a[3], a[4])
-->output
1
2    3    4    nil
4
2    3    nil    nil

◆ table.sort (table [, comp])
按照给定的比较函数 comp 给表 table 排序,也就是从 table[1] 到 table[n],这里 n 表示 table的长度。 比较函数有两个参数,如果希望第一个参数排在第二个的前面,就应该返回 true,否则返回 false。 如果比较函数 comp 没有给出,默认从小到大排序。

local function compare(x, y) --从大到小排序
   return x > y         --如果第一个参数大于第二个就返回true,否则返回false
end
local a = { 1, 7, 3, 4, 25}
table.sort(a)           --默认从小到大排序
print(a[1], a[2], a[3], a[4], a[5])
table.sort(a, compare) --使用比较函数进行排序
print(a[1], a[2], a[3], a[4], a[5])
-->output
1    3    4    7    25
25    7    4    3    1

◆ table 其他非常有用的函数
LuaJIT 2.1 新增加的 table.new 和 table.clear 函数是非常有用的。前者主要用来预分配Lua table 空间,后者主要用来高效的释放 table 空间,并且它们都是可以被 JIT 编译的。具体可以参考一下 OpenResty 捆绑的 lua-resty-* 库,里面有些实例可以作为参考。

Lua 中,table 是最核心的数据结构,几乎所有复杂数据都依赖表来实现,Lua 标准库提供了一系列操作表的函数,主要集中在 table 模块中。以下是一些常用 table 函数的使用方法、功能及示例: ### table.insert(t, [pos,] value) - **功能**:向表 `t` 中插入元素。如果指定了 `pos`,则将 `value` 插入到表的 `pos` 位置;若未指定 `pos`,则默认将 `value` 插入到表的末尾。 - **示例**: ```lua local t = {1, 2, 3} table.insert(t, 4) -- 此时 t 为 {1, 2, 3, 4} table.insert(t, 2, 5) -- 此时 t 为 {1, 5, 2, 3, 4} ``` ### table.concat(list [, sep [, i [, j]]]) - **功能**:将表 `list` 中的元素连接成一个字符串。`sep` 是可选的分隔符,`i` 和 `j` 分别是可选的起始和结束索引。 - **示例**: ```lua local list = {"apple", "banana", "cherry"} local result = table.concat(list, ", ") -- result 为 "apple, banana, cherry" ``` ### table.move(src, a, b, dest [, dest_pos]) (Lua 5.3+) - **功能**:将表 `src` 中从索引 `a` 到 `b` 的元素移动到表 `dest` 中,从 `dest_pos` 位置开始。 - **示例**: ```lua local src = {1, 2, 3, 4, 5} local dest = {10, 20} table.move(src, 2, 4, dest, 3) -- dest 为 {10, 20, 2, 3, 4} ``` ### table.pack(...) (Lua 5.2+) - **功能**:将所有参数打包成一个表,该表有一个 `n` 字段,表示元素的数量。 - **示例**: ```lua local t = table.pack(1, 2, 3) -- t 为 {1, 2, 3, n = 3} ``` ### table.remove(list [, pos]) - **功能**:从表 `list` 中移除指定位置 `pos` 的元素,并返回该元素。若未指定 `pos`,则默认移除表的最后一个元素。 - **示例**: ```lua local list = {1, 2, 3, 4} local removed = table.remove(list, 2) -- removed 为 2,list 为 {1, 3, 4} ``` ### table.sort(list [, comp]) - **功能**:对表 `list` 中的元素进行排序。`comp` 是可选的比较函数,若未提供,则默认按升序排序。 - **示例**: ```lua local list = {3, 1, 4, 2} table.sort(list) -- list 为 {1, 2, 3, 4} ``` ### table.unpack(list [, i [, j]]) - **功能**:返回表 `list` 中从索引 `i` 到 `j` 的元素。若未指定 `i`,则默认从 1 开始;若未指定 `j`,则默认到表的最后一个元素。 - **示例**: ```lua local list = {1, 2, 3, 4} local a, b, c = table.unpack(list, 2, 4) -- a 为 2,b 为 3,c 为 4 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值