表table
示Lua语言中特有的强大武器,是用来存储其他元素的一个实体,通常这些元素都是相互关联的,即使成对元素的一个集合,每对元素都有一个关键字(键名)和一个值组成。在表中可以使用关键字来索引与其唯一对应的值。此外,可使用{}
来构造表。
table
类型实现了“关联数组(associative array)”,关联数组是一种具有特殊索引的数组。不仅可以通过整数来所以,还可使用字符串或其他类型的值(除了nil
)来索引。
table
没有固定大小,可以动态地添加任意数量的元素到一个table
中。
table
是Lua中主要的数据结构,具有强大的功能。基于table
可以以一种简单、统一、高效的方式来表示普通数组、符号表(symbol table)、集合、记录、队列和其他数据结构。
Lua通过table
来标识模块(module)、包(package)、对象(object)。例如,io.read
表示io模块的read函数,对于Lua而言表示使用字符串read作为key来索引table io。
在Lua中 table
既不是值也不是变量,而是对象。可以将table
想象成一种动态分配的对象,程序仅持有一个对它的引用(或指针),Lua不会暗中产生table
的副本或创建新的table
。
Lua中无需声明一个table
,事实上可没有办法可以声明table
。table
的创建是通过构造表达式(constructor expression)完成的,最简单的构造表达式是{}
。
$ lua
> a = {} -- 使用构造表达式创建table
> k = "x"
> a[k] = 20
> a[20] = "great"
> print(a["x"]) -- 20
> k = 20
> print(a[k]) -- "great"
> a["x"] = a["x"] + 1
> print(a["x"]) -- 11
table 永远是匿名的(anonymous),一个持有table的变量与table自身之间没有固定的关联性。
$ lua
> a = {}
> a["x"] = 10
> b = a
> print(b["x"]) -- 10
> b["x"] = 20
> print(a["x"]) -- 20
> a = nil
> b = nil
当程序再也没有对table的引用时,Lua的垃圾收集器(garbage collector)最终会删除该table,并复用它的内存。
table可以用不同类型的索引来访问其值,当需要容纳新条目(entry)时,table会自动增长。
$ lua
> a = {}
> for i=1,1000 do a[i]=i*2 end
> print(a[9])
> a["x"] = 20
> print(a["x"]) -- 20
> print(a["y"]) -- nil
当table的某个元素没有初始化时,它的内容就为nil。
为了表示一条记录,可将字段名作为索引。Lua对于诸如a["name"]
的写法提供了一种简便的语法糖(syntactic sugar),可直接使用a.name
。
$ lua
> a = {}
> a.x = 10
> print(a.x) -- 10
> print(a.y) -- nil
点的写法更明确的暗示读者,将table作为一条记录来使用,每条记录都有一组固定的、预定义的key。而字符串的写法可能暗示了该table会以任何字符串作为key。
$ lua
> a = {}
> x = "y"
> a[x] = 10
> print(a[x])
10
> print(a.x)
nil
> print(a.y)
10
若要表示一个传统的数组或线性表,仅需以整数作为key来使用table即可。无需声明大小值,直接初始化元素即可。
$ lua
> a = {}
-- 读取10行并存储到一个table中
> for i=1,10 do a[i]=io.read() end
可使用任何值作为table的索引,也可以使用任意数字作为数组索引的初始值,但就Lua的习惯而言,数组通常是以1作为索引的起始值。
Lua5.1中,长度操作符#
用于返回一个数组或线性表的最后一个索引值或其大小。
$ lua
> for i=1,#a do print(a[i]) end
对于所有未初始化的元素的索引结果都是nil
,Lua将nil
作为界定数组结尾的标志。当一个数组有空隙(hole)时,即中间含有nil时,长度操作符会认为这些nil元素就是结尾标记。
若需要处理含有空隙的数组,可使用函数table.maxn()
,它将返回一个table的最大正索引数。
$ lua
> a = {}
> a[10000] = 1
> print(table.maxn(a))
10000
表的创建
- Lua的表是哈希表和数组的结合体
-- 初始化空表
array = {}
-- 删除表元素,置为nil即可。
array["name"] = nil
-- 将函数作为表元素进行添加
tbl = {}
tbl.fn = function()
print("test")
end
tbl.fn()
-
table
是Lua的一种数据结构,用来创建不同的数据类型,如数组和字典。 -
table
作为关联数组,可使用除nil
外的值做数组的索引 -
table
大小是不固定的,可根据自己的需要进行扩容。
定义数组型的表
-- 定义数组型的表
array = {val1, val2, val3}
array = {[1]=val1, [2]=val2, [3]=val3}
-- 使用#获取字符串的长度,在数组中#可获取数组中元素的个数。
print(#array)
-- 数组长度
x = 10
y = 20
z = 30
array = {x, y, z}
print(#array)
-- 数组循环遍历
for i = 1, #array, 1 do
print(i, array[i])
end
array = {}
table.insert(array, 1, 10)
table.insert(array, 2, 20)
table.insert(array, 3, 30)
table.remove(array, 1)
table.sort(array)
for i = 1, #array, 1 do
print(i, array[i])
end
-- 创建函数的表作为自定义的函数库
fnlib = {}
fnlib.echo = function(str)
print(str)
end
fnlib.echo("test")
获取系统变量
for k,v in pairs(_G) do
print(k,v)
end
当Lua表作为配置
config = {
game = {
debug=true
},
sound = {
isBgMusicOpen= true,
isEffectOpen = false
},
texture = {
PLIST_DIR = "res/plist",
PACKER_TEXTUER_DIR = "res/images"
}
}
for k,v in pairs(_ENV) do
print(k,v)
end
Lua的整体效率是很高的,其中table
的实现很巧妙的为此贡献最大。
Lua的Table充当了“数组””和“映射”的双重功能,让Table做数组使用时尽量少效率惩罚。
表的索引
表可以使用字符串作为键,如果使用了则表在自动分配键的时候,会跳过此元素,将键分配给下一个元素。
local tbl = {100, username="alice", 1}
print(tbl[1], tbl[2], tbl.username) -- 100 1 alice
表的操作
local tbl = {"lua", "c", "c++", "c#", "java"}
-- 元素拼接
-- local str = ""
-- str = table.concat(tbl, ",")
-- print( str ) -- lua,c,c++,c#,java
-- 指定索引拼接
-- str = table.concat(tbl, ",", 2, 4)
-- print(str) -- c,c++,c#
-- 插入元素
table.insert(tbl, "js")
print( tbl, #tbl, table.concat(tbl, ","))-- lua,c,c++,c#,java,js
table.insert(tbl, 1, "php")
print( tbl, #tbl, table.concat(tbl,",")) -- php,lua,c,c++,c#,java,js
-- 移除元素
tbl[1] = nil -- 由于元素置空后,占用的位置仍旧存在,不能使用table.concat和ipairs
print( tbl, #tbl)
for i,v in pairs(tbl) do
print(i,v)
end
-- 移除指定位置的元素
table.remove(tbl, 1)
print(table.concat(tbl, ",")) -- lua,c,c++,c#,java,js
-- 默认移除末尾元素
table.remove(tbl)
print(tbl, #tbl, table.concat(tbl, ",")) -- lua,c,c++,c#,java
表的排序
local tbl = {"lua", "c", "c++", "c#", "java"}
table.insert(tbl, "C")
table.insert(tbl, "PHP")
-- 顺序
table.sort(tbl)
print( table.concat(tbl,",") ) -- C,PHP,c,c#,c++,java,lua
-- 逆序
table.sort(tbl, function(x,y)
return x > y
end)
print( table.concat(tbl, ",") ) --lua,java,c++,c#,c,PHP,C
表的最值
local tbl = {}
for i=1,10 do
table.insert(tbl, math.random(1, 100))
end
print(table.concat(tbl, ",")) -- 1,57,20,81,59,48,36,90,83,75
for k,v in pairs( tbl ) do
print(k,v)
end
-- lua5.3移除table.maxn
function table_max(tbl)
local val = nil
for k,v in pairs(tbl) do
if val == nil then
val = v
end
if val < v then
val = v
end
end
return val
end
function table_min(tbl)
local val = nil
for k,v in pairs(tbl) do
if val == nil then
val = v
end
if val > v then
val = v
end
end
return val
end
print(table_min(tbl), table_max(tbl)) --1 90