在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
输出
在Table内部通过索引来声明 1 2 3 4 local table = { [1] = 'hello', [5] = 'world' } for i, v in pairs(table) do print(table[i]) end
输出
在Table内部不通过索引来声明 1 2 3 4 local table = {'hello','world'} for k, v in pairs(table) do print(k,v) end
输出
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
输出
这时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())
输出
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