Lua: Language: Sequence

 10th November 2022 at 2:32pm

有且仅有从 1 开始的连续 key 的 table 被认为是 sequence:

t1 = {3, 5, 1}       -- 是 sequence
t2 = {3, nil, 1}     -- 中间有洞,不是 sequence
t3 = {3, [100] = 1}  -- 中间有长一段空的,不是 sequence

对于 sequence,# 操作符可以看其长度:

t1 = {3, 5, 1}
#t1   --> 3

对于非 sequence,# 操作符的结果是未定义的。

Sequence 的常见操作:

a = {4, 3, 1}

-- Traverse:
for i = 1, #a do
    print(a[i])
end

-- Append (take 1):
a[#a + 1] = v
-- Append (take 2):
table.insert(a, v)

table 库中的大部分函数是为 sequence 服务的。table.inserttable.remove 使得可以容易实现 queue / stack / double queue 数据结构。

table 库中还有一个强大的函数 table.move (a1, f, e, t [,a2])

Moves elements from the table a1 to the table a2, performing the equivalent to the following multiple assignment: a2[t],··· = a1[f],···,a1[e]. The default for a2 is a1. The destination range can overlap with the source range. The number of elements to be moved must fit in a Lua integer.

Returns the destination table a2.

比如:

-- 这段代码做一个插入,等价于 table.insert(a, 2, "10")
table.move(a, 2, #a, 3)
a[2] = 10

-- 这段代码删除第一个元素。
-- 值得注意的是,move 实际上是拷贝而不是真的移动,因此你需要删掉最后一个数据。
table.move(a, 2, #a, 1)
a[#a] = nil

-- 实用功能 1:(浅)拷贝整个 table
b = table.move(a, 1, #a, 1, {})

-- 实用功能 2:把 table a 的所有元素 append 到 table b 的末尾
table.move(a, 1, #a, #b + 1, b)

table.pack() 则可以把多个值打包成一个 sequence:

> utf8.codepoint("你好,世界", 1, -1)
20320	22909	65292	19990	30028
> t = table.pack(utf8.codepoint("你好,世界", 1, -1))
> t[1]
20320
> t[5]
30028