表标准库提供了操作表和序列的一些常用函数
table.insert
函数 table.insert
向序列的指定位置插入一个元素,其他元素依次后移。例如,对于列表 t = {10, 20, 30}
,在调用 table.insert(t, 1, 5)
后它会变成 {15, 10, 20, 30}
,另一种特殊但常见的情况是调用 insert
时不指定位置,此时该函数会在序列的最后插入指定的元素,而不会移动任何元素。例如,下属代码从标准输入中按照读入内容并将其保存到一个序列中:
t = {} for line in io.lines() do table.insert(t, line) end print(#t) --> (读取的行数)
table.remove
函数 table.remove
删除并返回序列指定位置的元素,然后将其后的元素向前移动填充删除元素后造成的空洞。如果在调用该函数时不指定位置,该函数会删除序列的最后一个元素。
数据结构实现
借助这两个函数,可以很容易地实现栈( Stack
)、队列( Queue
)和双端队列( Double Queue
)。以栈的实现为例,我们可以使用 t = {}
来表示栈, Push
操作可以使用 table.insert(t, x)
实现, Pop
操作可以使用 table.remove(t)
实现,调用 table.insert(t, 1, x)
可以实现在栈的顶部进行插入,调用 table.remove(t, 1)
可以从栈的顶部移除。由于后两个函数涉及表中其他元素的移动,所以其运行效率并不是特别高。当然,由于 table
标准库中的这些函数是使用 C语言
实现的,所以移动元素所涉及循环的性能开销也并不是太昂贵。因而,对于几百个元素组成的小数组来说这种实现已经足矣。
table.move
Lua5.3
对于移动表中的元素引入了一个更通用的函数 table.move(a, f, e, t)
,调用该函数可以将表 a
从索引 f
到 e
的元素(包含索引 f
和索引 e
对应的元素本身)移动到位置 t
上。例如,如下代码可以在列表 a
的开头插入一个元素:
table.move(a, 1, #a, 2) a[1] = newElement
如下的代码可以删除第一个元素:
table.move(a, 2, #a, 1) a[#a] = nil
注意
在计算机领域,移动( move
)实际上是将一个值从一个地方拷贝( copy
)到另一个地方。因此,上面的例子中,我们必须在移动后显式地把最后一个元素删除。
函数 table.move
还支持使用一个表作为可选参数。当带有可选参数的表作为参数时,该函数将第一个表中的元素移动到第二个表中。例如: table.move(a, 1, #a, 1, {})
返回列表 a
的一个克隆( clone
)(通过将列表 a
中的所有元素拷贝到新列表中), table.move(a, 1, #a, #b + 1, b)
将列表 a
中的所有元素复制到列表 b
的末尾。