0Pricing
Lua Academy · 课时

将表用作数组

使用 table.insert 和 table.remove 创建并操作从索引 1 开始的数组。

将表用作数组 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

从 1 开始索引的数组

Lua 数组是键为连续整数的表,索引从 1 开始。这与从 0 开始的多数语言不同。在 Lua 中,这是统一的约定——所有标准库函数都假定使用从 1 开始的索引。访问越界位置会返回 nil,而不是报错。

local colors = {"red", "green", "blue"}
print(colors[1])   -- red
print(colors[2])   -- green
print(colors[3])   -- blue
print(colors[0])   -- nil (no index 0)
print(#colors)     -- 3 (length operator)

table.insert 和 table.remove

table.insert(t, val) 会将元素追加到末尾。table.insert(t, pos, val) 会在指定位置插入元素,并将后续元素向右移动。table.remove(t, pos) 会移除 pos 位置的元素(默认移除最后一个),将后续元素向左移动,并返回被移除的值。

local stack = {}
table.insert(stack, "first")
table.insert(stack, "second")
table.insert(stack, "third")
print(#stack)          -- 3

table.insert(stack, 2, "inserted")
print(stack[2])        -- inserted

local removed = table.remove(stack, 1)
print(removed)         -- first
print(stack[1])        -- inserted

使用表实现栈

Lua 表非常适合实现栈。使用 table.insert 入栈,使用 table.remove 出栈。默认情况下,这两个操作都从表的末尾进行,因此摊销时间复杂度为 O(1)。

local stack = {}

-- Push
table.insert(stack, 10)
table.insert(stack, 20)
table.insert(stack, 30)

-- Pop
print(table.remove(stack))  -- 30
print(table.remove(stack))  -- 20
print(#stack)               -- 1

使用表实现队列

队列(FIFO)可以使用表来实现,但 table.remove(t, 1) 的时间复杂度为 O(n),因为它会移动所有元素。对于高性能队列,请使用两个指针(头索引和尾索引),以避免移动元素。

local head, tail = 1, 0
local queue = {}

local function enqueue(v)
  tail = tail + 1
  queue[tail] = v
end

local function dequeue()
  if head > tail then return nil end
  local v = queue[head]
  queue[head] = nil
  head = head + 1
  return v
end

enqueue("a"); enqueue("b"); enqueue("c")
print(dequeue())  -- a
print(dequeue())  -- b

# 长度运算符

# 运算符返回表的“边界”:一个索引 i,满足 t[i] ~= nil 且 t[i+1] == nil。对于没有空缺的序列,这个索引等于数组长度。存在空缺(中间有 nil)时,# 的结果未定义——请使用 table.pack 或手动记录长度。

local t = {10, 20, 30, 40, 50}
print(#t)   -- 5

-- Safe for dense arrays
for i = #t, 1, -1 do
  io.write(t[i] .. " ")
end
print()  -- 50 40 30 20 10

数组切片

Lua 没有内置的切片功能,但您可以使用 table.move(Lua 5.3+)或手动循环提取子数组。table.move(a1, f, e, t, a2) 会将 a1[f..e] 中的元素复制到 a2,从位置 t 开始存放。

local src = {10,20,30,40,50,60}

-- Manual slice
local function slice(t, from, to)
  local result = {}
  for i = from, to do
    result[#result+1] = t[i]
  end
  return result
end

local sub = slice(src, 2, 4)
print(sub[1], sub[2], sub[3])  -- 20  30  40

反转数组

通过交换两端元素并逐步向中间移动,可以原地反转一个表。这是一种经典算法,无需额外内存即可用于任何 Lua 数组。

local function reverse(t)
  local n = #t
  for i = 1, math.floor(n / 2) do
    t[i], t[n - i + 1] = t[n - i + 1], t[i]
  end
end

local arr = {1, 2, 3, 4, 5}
reverse(arr)
for _, v in ipairs(arr) do
  io.write(v .. " ")
end
print()  -- 5 4 3 2 1

连接数组

要将两个数组合并为一个数组,请遍历第二个数组并追加其中的元素。在 Lua 5.3+ 中,table.move 可以高效地完成此操作。结果是一个新表,按顺序包含两个数组中的所有元素。

local function concat(a, b)
  local result = {}
  for _, v in ipairs(a) do result[#result+1] = v end
  for _, v in ipairs(b) do result[#result+1] = v end
  return result
end

local merged = concat({1,2,3}, {4,5,6})
for i, v in ipairs(merged) do
  io.write(v .. " ")
end
print()  -- 1 2 3 4 5 6

展平嵌套数组

递归地展平嵌套数组:如果某个元素是表,就递归处理它;否则将其追加到结果中。这是递归遍历表的自然应用。

local function flatten(t, result)
  result = result or {}
  for _, v in ipairs(t) do
    if type(v) == "table" then
      flatten(v, result)
    else
      result[#result+1] = v
    end
  end
  return result
end

local nested = {1, {2, 3}, {4, {5, 6}}, 7}
local flat = flatten(nested)
print(table.concat(flat, ", "))  -- 1, 2, 3, 4, 5, 6, 7

将数组用作集合

您可以使用表来实现集合,其中各个值作为键,而对应的值设为 true。检查集合成员的操作复杂度为 O(1)。从数组构建集合可以去除重复项。使用 pairs 遍历即可将其转换回数组。

local function toSet(arr)
  local set = {}
  for _, v in ipairs(arr) do set[v] = true end
  return set
end

local nums = {3,1,4,1,5,9,2,6,5,3}
local set = toSet(nums)
local unique = {}
for k in pairs(set) do unique[#unique+1] = k end
table.sort(unique)
print(table.concat(unique, " "))  -- 1 2 3 4 5 6 9

快速检查

只传入一个参数调用 table.remove(t) 时会执行什么操作?

回顾:将表用作数组

总结:

  • Lua 数组是从 1 开始索引的表
  • 使用 table.insert/table.remove 实现入栈/出栈
  • 对于没有空洞的序列,#t 可获取长度
  • 栈:从末尾插入和移除元素(O(1))
  • 队列:使用头部和尾部指针,避免 O(n) 的移位操作
  • 将表用作集合,以实现 O(1) 的成员检查

常见问题解答

「将表用作数组」课时是免费的吗?

是的 — 「将表用作数组」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「将表用作数组」这节课中我会学到什么?

使用 table.insert 和 table.remove 创建并操作从索引 1 开始的数组。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「将表用作数组」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 将表用作数组
  2. 将表用作字典
  3. 使用 pairs 和 ipairs 遍历表
  4. 嵌套表和结构化数据
← 返回 Lua Academy