Chapter 20_1 table库
table库是由一些辅助函数构成,把table作为数组来操作,所有的函数都忽略传入参数的那张表中的非数字键。
无论如何,若一个操作需要取表的长度,这个表必须是一个真序列,或是拥有__len元方法。
提供了这样一些功能:从列表中插入和删除元素、对元素排序、连接一个数组中所有字符串。
- 插入和删除
函数table.insert用于将一个元素插入到一个数组指定位置,然后移动后续元素。
例如数组t = {10,20,30},当调用table.insert(t,1,15)后,t = {15,10,20,30}
如果insert函数没有指定位置参数,则会自动添加到数组末尾。
下面示例逐行读取输入,并将所有的行保存在一个数组中:
t = {}
for line in io.lines() do
table.insert(t , line)
end
print(#t) -->读入的行数
在Lua5.0的老版本中,这样写很正常,但是在最新的版本中,作者建议这样写:
t[#t+] = line --替换insert
函数table.remove会删除(并返回)数组指定位置上的元素,然后后面的元素前移。
当没有指定位置参数时,会删除最后一个元素。
通过这两个函数可以很方便地实现栈、队列、双向队列。可以用t = {}来初始化这种结构。
table.insert(t, x )等价于压入操作。
table.remove(t) 等价于弹出操作。
table.insert(t , 1 ,x )在结构的另一端插入一个新元素。
table.remove(t , 1 )会从这一端删除一个元素。
后两个操作不是很高效,因为必须移动元素。针对较小的数组可以这样使用。
- 排序
另一个有用的数组函数table.sort,之前在高阶函数中提到过。它可以对一个数组进行排序,可以指定一个可选的排序函数。
这个排序函数必须是一个可以接收两个列表内元素为参数的函数,如果希望第一个参数在排序结果中位于第二个参数值前,就应当返回true。
再次重现之前的例子:
network = {
{name = "arauna", IP = "210.26.20.30"},
{name = "brraial", IP = "210.26.45.33"},
{name = "lua", IP = "210.45.34.56"},
{name = "derain", IP = "210.26.23.76"},
}
table.sort(
network,
function (a,b) --这里的a,b参数分别是列表里的两个元素
return (a.name < b.name) -- "arauna" < "brraial" 为真,所以下面打印是按照name的升序打印
end
)
for k,v in pairs(network) do
print(k,v.name)
end
-->1 arauna
-->2 brraial
-->3 derain
-->4 lua
一个常见的错误是试图对一个table的索引进行排序。在table中,索引是一个无序的集合。
如果对它进行排序,则必须将它们复制到一个数组中,然后再对它进行排序。
下面演示一个示例:假设要读取一个源文件,并构建一个table记录每个函数并定义它的行号,table如下 :
lines = {
luaH_set = ,
luaH_get = ,
luaH_present = ,
}
现在要按照字母次序打印这些函数名。如果用pairs来遍历table,结果是无序的。由于这些名称是table的key,因此不能对她们进行直接排序。
应该先放在一个数组中排序:
a = {}
for n in pairs(lines) do
a[#a+] = n
end
table.sort(a) --对数组排序,按照默认的小于操作,结果为假,所以打印的是升序排列
for i , n in ipairs(a) do
print(n)
end
--> luaH_get
--> luaH_present
--> luaH_set
对于Lua来说,数组也是无序的,它们本质也是table。然而用户知道如何计算索引,因此在访问数组时,只要使用有序的索引,就可以顺序地访问数组。
这就是为什么必须要使用ipairs而不是pairs来遍历数组的原因。因为前者使用1、2、3....的顺序,后者采用table的原始顺序。
另一个更高级的方法,写一个迭代器,使它根据table key的次序来进行遍历。同时,还有一个可选的参数f,用于指定某种特殊次序:
function parisByKeys(t ,f )
local a = {}
for n in pairs(t) do a[#a + ] = n end
table.sort(a,f)
local i = --迭代器变量
return function() --迭代器函数
i = i +
return a[i],t[a[i]] --返回原table中的key和value,即函数名和行号
end
end
该函数先将key 排序到一个数组中,然后迭代这个数组,每步返回原table中的key和value。
通过这个函数就可以很容易地按照字母次序来打印那些函数名了:
for name , line in pairsByKeys(lines) do
print(name,line)
end
- 连接
之前也用到过table.connect,它接受一个字符串数组,并返回这些字符串连接后的结果。
它有一个可选参数,用于指定插到字符串之间的分隔符。
这个函数另外还接受两个可选参数,用于指定第一个和最后一个要连接的字符串索引。
下面这个函数是table.connect的一个扩展,它能处理嵌套的字符串数组:
function rconcat( t )
if type(t) ~= "table" then return r end
local res = {}
for i = , #t do
res[i] = rconcat(t[i]) --递归调用自己,以此来连接所有可能嵌套的字符串数组。
end
return table.concat(res)
end
最后调用concat来连接这些结果:
print(rconcat{{"a",{" nice"}} , " and",{{" long"}, {" list"}}})
--> a nice and long list
- 扩展两个有用的函数
table.pack(...)函数返回一个新表,以1、2、3...为key,参数为值的新表。并将“n”这个域设置为参数的总和。
这个新表不一定是一个序列。
table.unpack(list)函数返回列表中的元素,可以加两个参数i ,j 表示要返回的起始索引对应的值。
等价于:
return list[i],list[i+]......,list[j]
所以,如果不设置i 和j ,就表示默认从1到#list
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition 》 和 Lua参考手册
Chapter 20_1 table库的更多相关文章
- Lua 之table库
标准table库 table.concat(table, sep, start, end) concat是concatenate(连锁, 连接)的缩写,table.concat()函数列出参数中指定 ...
- Chapter 18_0 数学库
从今天起,开始接触Lua的标准库(数学库.table库.字符库.I/O库.操作系统库.调试库). 一路走来,从最基本的变量.函数.迭代器.协同程序到稍微复杂的元表.元方法.环境.模块,以及最后被整蒙了 ...
- Lua整理——table库
table属性 table库是有一些辅助函数构成的,这些函数将table作为数组来操作. 当中.有对列表中插入和删除元素的函数,有对数组元素进行排序的函数.还有对链接一个数组中全部字符串的函数. 0. ...
- Lua table库整理(v5.1)
这个库提供了表处理的通用函数. 所有函数都放在表 table. 无论何时,若一个操作需要取表的长度, 这张表必须是一个真序列. table.concat(list, [, sep, [, i , [, ...
- Chapter 19_0 位操作库
位操作库是Lua5.2版本里添加的库,所有函数放在bit32 table里.(bit32只能针对32位整数运算) 在Lua5.3版本里,bit32库被废弃掉.不过可以使用一个外部兼容库,但是最好直接用 ...
- lua的table库中经常使用的函数
lua提供了一些辅助函数来操作table. 比如,从list中insert和remove元素,对array的元素进行sort.或者concatenate数组中的全部strings.以下就具体地解说这些 ...
- Chapter 17_3 table的默认值
对象属性 有很多情况需要把有些属性绑定到某个对象,例如:函数与其名称.table的默认值.数组大小等... 当对象是一个table时,可以通过适当的key将属性存储在这个table中. 如果对象不是一 ...
- chapter 13_3 table访问的元方法
前两节的算术类.关系类运算符的元方法都为各种错误情况定义了行为,它们不会改变语言的常规行为. 但是Lua还提供了两种可以改变table行为的方法: 一种是查询table中不存在的字段.一种是修改tab ...
- lua的table库
函数列表: table.insert(table,[ pos,] value) table.remove(table[, pos]) table.concat(table[, sep[, i[, j] ...
随机推荐
- phantomjs初次认识
phantomjs初次认识 最近没什么重要的任务,就抽空看了看项目组爬虫小组的代码,因为我们的爬虫主要是以python的scrapy框架为主,看起来比较方便.在看代码的时候看到一个叫phantomjs ...
- Oracle用脚本语言导入SCOTT用户
许多Oracle新手都遇到这样的问题,安装Oracle之后没有SCOTT用户,那就自己加入吧,打开Oracle 命令窗口复制下面SQL脚本直接输入就行了,包含了测试学习的DEPT.EMP.BONUS. ...
- Go语言Web框架gwk介绍 3
Go语言Web框架gwk介绍 (三) 上一篇忘了ChanResult ChanResult 可以用来模拟BigPipe,定义如下 type ChanResult struct { Wait syn ...
- tastypie Django REST framework
Its one of the primary authors' lecture on pyCon: http://www.youtube.com/watch?v=Zv26xHYlc8s&nor ...
- SQL Server 2014新特性:五个关键点带你了解Excel下的Data Explorer
SQL Server 2014新特性:五个关键点带你了解Excel下的Data Explorer Data Explorer是即将发布的SQL Server 2014里的一个新特性,借助这个特性讲使企 ...
- centos6.5 搭建nginx1.6.0 +gridfs +mongodb2.4..10环境
一) 缘由 因为公司业务需要,需要搭建图片服务器,需求很简单:读取+上传图片,当时第一考虑用nginx来作,但考虑到单纯用nginx来作,无法水平扩展和管理,一旦遇到海量图片,就无办法 扩展.所以考虑 ...
- ok6410 u-boot-2012.04.01移植五支持DM9000
继ok6410 u-boot-2012.04.01移植四后,开发板基本已支持MLC NAND,但还有一些细节地方修改,这节增加DM9000支持,通过网卡tftp程序到内存,接着通过NAND命令写到NA ...
- Linux内核 hlist_head/hlist_node结构解析
内核中的定义: struct hlist_head { struct hlist_node *first;}; struct hlist_node { struct hlist_node ...
- CSS实现导航条Tab的三种方法
前面的话 导航条Tab在页面中非常常见,本文说详细介绍CSS实现导航条Tab的三种方法 布局 根据上图所示,先规定几个定义,上图的模块整体叫做导航,由导航标题和导航内容组成.要实现上图所示的布 ...
- Java多线程基础——线程间通信
在使用多线程的时候,经常需要多个线程进行协作来完成一件事情.在前面两章分析了Java多线程的基本使用以及利用synchronized来实现多个线程同步调用方法或者执行代码块.但上面两章的内容涉及到的例 ...