Lua之Table个人总结

3.8k 词

在lua中Table是数组和集合的混合物。作为数组时,可以使用除了nil以外的值作为索引。


Table的构造

利用下标来标明元素
1
2
3
4
5
6
local table  = {}
table[1]='hello'
table[5]='world'
for i,v in pairs(table)do
print(table[i])
end

输出

1
2
1	hello
5 world

在Table内部通过索引来声明
1
2
3
4
local table = { [1] = 'hello', [5] = 'world' }
for i, v in pairs(table) do
print(table[i])
end

输出

1
2
1	hello
5 world

在Table内部不通过索引来声明
1
2
3
4
local table = {'hello','world'}
for k, v in pairs(table) do
print(k,v)
end

输出

1
2
1	hello
2 world


Note:

1,可以看到通过下标标明元素(方法1)和在内部通过索引方式(方法2)构造的table是一样的。如果不声明索引(方法3),则默认为数字,且从1开始。

2,索引可以为字符串。

1
2
3
4
5
6
local table  = {}
table[1]='hello'
table["skr"]='world'
for k, v in pairs(table) do
print(k,v)
end

或者是

1
2
3
4
local table = { [1] = 'hello', skr = "world" }
for k, v in pairs(table) do
print(k, v)
end

输出

1
2
1	hello
skr world

这时table有点像Java的HashMap,下标作为key。

3,如果索引为数字访问方式为 table[1]
如果索引为其他类型,访问方式为 table.skr 或者是 table[‘skr’](注意 [ ] 内为字符串,两侧有引号)

1
2
3
4
print(table[1])         --输出hello
print(table.skr) --输出world
print(table[skr]) --输出nil(没有引号,错误)
print(table['skr']) --输出world(有引号,正确)

4,#运算符

利用#运算符可以获得table中使用数字做key的元素总数。

1
2
local table = { [1] = 'hello', skr = "world", _2 = "123" }
print(#table) --输出1,只有索引为1的元素才会被计算,skr和_2都是字符串


Table的其他用法

上面的例子可以看到,Lua的Table,索引Key为数字时像Java的ArrayList,索引为字符串的时候像Java的HashMap。Java的HashMap可以存储对象,Lua的Table也可以。

1
2
3
4
5
6
7
8
9
10
11
12
13
local CPU = { name = 'CPU', cost = 400 }
local Monitor = { name = 'bird', cost = 200 }
local Memory = { name = 'memory', cost = 100 }
local Computer = {
CPU,
cpu = Monitor
}
Computer.memory = Memory
Computer[6] = Memory

for k, v in pairs(Computer) do
print(k, v.name, v.cost)
end

输出

1
2
3
4
1	CPU	400   --数字索引
cpu bird 200 2 --字符串索引
6 memory 100 2 --数字索引,构造后添加
memory memory 100 4 --字符串索引,构造后添加

Table中利用索引存储Table,这种思想类似面向对象的封装。而对象是由属性和方法组成,在Lua中,对象由Table作属性,function作方法,共同组成对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local CPU = { name = 'CPU', cost = 400 }
local Monitor = { name = 'bird', cost = 200 }
local Memory = { name = 'memory', cost = 100 }
local Computer = {
description = "this is a computer",
cpu = CPU,
monitor = Monitor,
memory = Memory
}

function Computer.getDescription()
return Computer.description
end

print(Computer.getDescription())

输出

1
this is a computer

Table的常用方法

这些方法的使用类似Java的静态方法

table.insert(table,pos,value):往table中第pos中插入value的值。如果pos已存在,则往后移动。
1
2
3
4
5
6
7
8
9
10
print('before insert')
local tb = { '1', '2', '3', '5' }
for k, v in pairs(tb) do
print(k, v)
end
table.insert(tb, 2, '6')
print('after insert')
for k, v in pairs(tb) do
print(k, v)
end

输出

1
2
3
4
5
6
7
8
9
10
11
before insert
1 1
2 2
3 3
4 5
after insert
1 1
2 6
3 2
4 3
5 5

往tb中index=2的地方插入了6,原来index=2的位置变成了3。类似Java的list.add(index,object).

如果没有索引,则往最后的地方插入。类似Java的list.add(object)

pos,否则会报错。

table.remove(table,pos):和insert类似
table.sort(table, 排序规则)

排序规则为自定义排序规则,缺省为升序

下面的例子是定义了一个排序规则为年龄降序的排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
local people = {
{ name = 'a', age = 11 },
{ name = 'b', age = 14 },
{ name = 'c', age = 12 },
{ name = 'd', age = 10 },
}

function sortByAge(a, b)
return a.age > b.age
end

function printArray(showText, array)
print(showText)
for i, v in ipairs(array) do
print(v.name, v.age)
end
end

printArray('before', people)
table.sort(people, sortByAge)
printArray('after', people)

其中sortByAge(object1,object2)需要传入两个对象。如果返回true的话就交换位置,由于这里用的是大于,则表示从大到小排序,则为降序。输出结果为:

1
2
3
4
5
6
7
8
9
10
before
a 11
b 14
c 12
d 10
after
b 14
c 12
a 11
d 10

如果改变排序规则,比较名字。使用升序,输出应该为abcd

1
2
3
function sortByName(a, b)
return a.name < b.name
end

输出的确为a-b-c-d

1
2
3
4
5
after
a 11
b 14
c 12
d 10

另外,字符串的排序应该是按照首个字符的AscII码排序。

1
2
3
4
5
6
local people = {
{ name = '+a', age = 11 },
{ name = 'ab', age = 14 },
{ name = 'Dc', age = 12 },
{ name = '9d', age = 10 },
}

其中+的Ascii码为43,a为97,D为68,9为57,输出结果为

1
2
3
4
5
after
+a 11
9d 10
Dc 12
ab 14

table.concat(table[,间隔符[,start[,end]]])

把table内部的元素从start开始到end,以 间隔符 拼接,拼接后的对象属性为String

1
2
3
4
5
6
7
local tb = {'1','2','3','4'}
local s1 = table.concat(tb,'*',2,3)
local s2 = table.concat(tb)
print(s1)
print(type(s1))
print(s2)
print(type(s2))

上面展示了把table的每个元素拼接,元素之间以 * 和 ‘’(空字符串) 间隔,输出

1
2
3
4
2*3  --从第二到第三个元素,期间以*连接
string
1234 --不带参数表示从头到尾,以空字符串连接
string