表作为数组 #

一、数组基础 #

1.1 创建数组 #

lua
-- 创建空数组
local arr = {}

-- 创建带初始值的数组
local arr1 = {1, 2, 3, 4, 5}
local arr2 = {"a", "b", "c"}

-- 使用循环创建
local arr3 = {}
for i = 1, 10 do
    arr3[i] = i * 2
end

1.2 数组索引 #

lua
local arr = {"a", "b", "c", "d", "e"}

-- Lua 数组索引从 1 开始
print(arr[1])  -- a(第一个元素)
print(arr[5])  -- e(最后一个元素)

-- 获取长度
print(#arr)    -- 5

-- 访问最后一个元素
print(arr[#arr])  -- e

1.3 数组与 nil #

lua
-- 数组应该是连续的
local good_arr = {1, 2, 3, 4, 5}
print(#good_arr)  -- 5

-- 避免数组中出现 nil
local bad_arr = {1, 2, nil, 4}
print(#bad_arr)   -- 不确定

-- 删除元素应该移动后续元素
local arr = {1, 2, 3, 4, 5}
arr[3] = nil      -- 不推荐
table.remove(arr, 3)  -- 推荐

二、table 库函数 #

2.1 table.insert #

lua
local arr = {1, 2, 3}

-- 在末尾插入
table.insert(arr, 4)
print(table.concat(arr, ", "))  -- 1, 2, 3, 4

-- 在指定位置插入
table.insert(arr, 2, "new")
print(table.concat(arr, ", "))  -- 1, new, 2, 3, 4

-- 使用返回值(Lua 5.3+)
local new_arr = table.insert({1, 2}, 3)  -- 返回原表

2.2 table.remove #

lua
local arr = {1, 2, 3, 4, 5}

-- 删除最后一个元素
local last = table.remove(arr)
print(last)  -- 5
print(table.concat(arr, ", "))  -- 1, 2, 3, 4

-- 删除指定位置
local removed = table.remove(arr, 2)
print(removed)  -- 2
print(table.concat(arr, ", "))  -- 1, 3, 4

2.3 table.sort #

lua
-- 升序排序
local arr = {3, 1, 4, 1, 5, 9, 2, 6}
table.sort(arr)
print(table.concat(arr, ", "))  -- 1, 1, 2, 3, 4, 5, 6, 9

-- 降序排序
table.sort(arr, function(a, b)
    return a > b
end)
print(table.concat(arr, ", "))  -- 9, 6, 5, 4, 3, 2, 1, 1

-- 自定义排序
local users = {
    {name = "Bob", age = 30},
    {name = "Alice", age = 25},
    {name = "Charlie", age = 35}
}

table.sort(users, function(a, b)
    return a.age < b.age
end)

for _, user in ipairs(users) do
    print(user.name, user.age)
end
-- Alice    25
-- Bob      30
-- Charlie  35

2.4 table.concat #

lua
local arr = {"a", "b", "c", "d"}

-- 连接所有元素
print(table.concat(arr))       -- abcd
print(table.concat(arr, ", ")) -- a, b, c, d

-- 指定范围
print(table.concat(arr, ", ", 2, 4))  -- b, c, d

2.5 table.move(Lua 5.3+) #

lua
local arr = {1, 2, 3, 4, 5}

-- 移动元素
table.move(arr, 1, 3, 4)  -- 将 1-3 移动到从 4 开始的位置
print(table.concat(arr, ", "))  -- 1, 2, 3, 1, 2, 3

-- 复制到另一个表
local src = {1, 2, 3}
local dst = {10, 20, 30, 40, 50}
table.move(src, 1, 3, 2, dst)
print(table.concat(dst, ", "))  -- 10, 1, 2, 3, 50

三、数组操作 #

3.1 查找元素 #

lua
-- 线性查找
local function find(arr, value)
    for i, v in ipairs(arr) do
        if v == value then
            return i
        end
    end
    return nil
end

local arr = {3, 1, 4, 1, 5, 9}
print(find(arr, 4))  -- 3
print(find(arr, 7))  -- nil

-- 查找满足条件的元素
local function find_if(arr, predicate)
    for i, v in ipairs(arr) do
        if predicate(v, i) then
            return v, i
        end
    end
    return nil, nil
end

local value, index = find_if({1, 2, 3, 4, 5}, function(v)
    return v > 3
end)
print(value, index)  -- 4    4

3.2 过滤数组 #

lua
local function filter(arr, func)
    local result = {}
    for _, v in ipairs(arr) do
        if func(v) then
            table.insert(result, v)
        end
    end
    return result
end

local evens = filter({1, 2, 3, 4, 5, 6}, function(x)
    return x % 2 == 0
end)
print(table.concat(evens, ", "))  -- 2, 4, 6

3.3 映射数组 #

lua
local function map(arr, func)
    local result = {}
    for i, v in ipairs(arr) do
        result[i] = func(v, i)
    end
    return result
end

local doubled = map({1, 2, 3, 4, 5}, function(x)
    return x * 2
end)
print(table.concat(doubled, ", "))  -- 2, 4, 6, 8, 10

3.4 归约数组 #

lua
local function reduce(arr, func, initial)
    local acc = initial
    for _, v in ipairs(arr) do
        acc = func(acc, v)
    end
    return acc
end

local sum = reduce({1, 2, 3, 4, 5}, function(acc, v)
    return (acc or 0) + v
end)
print(sum)  -- 15

四、栈操作 #

4.1 实现栈 #

lua
local Stack = {}
Stack.__index = Stack

function Stack.new()
    return setmetatable({data = {}}, Stack)
end

function Stack:push(value)
    table.insert(self.data, value)
end

function Stack:pop()
    return table.remove(self.data)
end

function Stack:peek()
    return self.data[#self.data]
end

function Stack:size()
    return #self.data
end

function Stack:is_empty()
    return #self.data == 0
end

-- 使用
local stack = Stack.new()
stack:push(1)
stack:push(2)
stack:push(3)
print(stack:pop())   -- 3
print(stack:peek())  -- 2

五、队列操作 #

5.1 实现队列 #

lua
local Queue = {}
Queue.__index = Queue

function Queue.new()
    return setmetatable({data = {}}, Queue)
end

function Queue:enqueue(value)
    table.insert(self.data, value)
end

function Queue:dequeue()
    return table.remove(self.data, 1)
end

function Queue:front()
    return self.data[1]
end

function Queue:size()
    return #self.data
end

function Queue:is_empty()
    return #self.data == 0
end

-- 使用
local queue = Queue.new()
queue:enqueue(1)
queue:enqueue(2)
queue:enqueue(3)
print(queue:dequeue())  -- 1
print(queue:front())    -- 2

5.2 双端队列 #

lua
local Deque = {}
Deque.__index = Deque

function Deque.new()
    return setmetatable({data = {}}, Deque)
end

function Deque:push_left(value)
    table.insert(self.data, 1, value)
end

function Deque:push_right(value)
    table.insert(self.data, value)
end

function Deque:pop_left()
    return table.remove(self.data, 1)
end

function Deque:pop_right()
    return table.remove(self.data)
end

function Deque:peek_left()
    return self.data[1]
end

function Deque:peek_right()
    return self.data[#self.data]
end

六、常用算法 #

6.1 二分查找 #

lua
local function binary_search(arr, value)
    local left, right = 1, #arr
    
    while left <= right do
        local mid = math.floor((left + right) / 2)
        if arr[mid] == value then
            return mid
        elseif arr[mid] < value then
            left = mid + 1
        else
            right = mid - 1
        end
    end
    
    return nil
end

local sorted = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
print(binary_search(sorted, 7))  -- 7
print(binary_search(sorted, 11)) -- nil

6.2 快速排序 #

lua
local function quick_sort(arr, left, right)
    left = left or 1
    right = right or #arr
    
    if left >= right then
        return
    end
    
    local pivot = arr[math.floor((left + right) / 2)]
    local i, j = left, right
    
    while i <= j do
        while arr[i] < pivot do i = i + 1 end
        while arr[j] > pivot do j = j - 1 end
        
        if i <= j then
            arr[i], arr[j] = arr[j], arr[i]
            i = i + 1
            j = j - 1
        end
    end
    
    quick_sort(arr, left, j)
    quick_sort(arr, i, right)
end

local arr = {3, 1, 4, 1, 5, 9, 2, 6}
quick_sort(arr)
print(table.concat(arr, ", "))  -- 1, 1, 2, 3, 4, 5, 6, 9

6.3 去重 #

lua
local function unique(arr)
    local seen = {}
    local result = {}
    
    for _, v in ipairs(arr) do
        if not seen[v] then
            seen[v] = true
            table.insert(result, v)
        end
    end
    
    return result
end

local arr = {1, 2, 2, 3, 3, 3, 4}
print(table.concat(unique(arr), ", "))  -- 1, 2, 3, 4

七、多维数组 #

7.1 创建二维数组 #

lua
-- 创建 m x n 的二维数组
local function create_matrix(m, n, initial)
    initial = initial or 0
    local matrix = {}
    for i = 1, m do
        matrix[i] = {}
        for j = 1, n do
            matrix[i][j] = initial
        end
    end
    return matrix
end

local grid = create_matrix(3, 4, 0)

-- 访问
grid[2][3] = 5

-- 遍历
for i = 1, #grid do
    for j = 1, #grid[i] do
        io.write(grid[i][j] .. " ")
    end
    io.write("\n")
end

7.2 矩阵操作 #

lua
-- 矩阵加法
local function matrix_add(a, b)
    local result = {}
    for i = 1, #a do
        result[i] = {}
        for j = 1, #a[i] do
            result[i][j] = a[i][j] + b[i][j]
        end
    end
    return result
end

-- 矩阵转置
local function transpose(matrix)
    local result = {}
    for i = 1, #matrix[1] do
        result[i] = {}
        for j = 1, #matrix do
            result[i][j] = matrix[j][i]
        end
    end
    return result
end

八、性能优化 #

8.1 预分配数组 #

lua
-- 预分配数组大小
local function preallocate(n)
    local arr = {}
    for i = 1, n do
        arr[i] = 0
    end
    return arr
end

-- 使用 table.new(LuaJIT)
-- local arr = table.new(1000, 0)

8.2 避免频繁插入 #

lua
-- 不推荐:频繁插入
local arr = {}
for i = 1, 10000 do
    table.insert(arr, i)
end

-- 推荐:直接赋值
local arr = {}
for i = 1, 10000 do
    arr[i] = i
end

九、总结 #

本章介绍了 Lua 表作为数组的使用:

  1. 数组基础:创建、索引、长度
  2. table 库:insert、remove、sort、concat、move
  3. 数组操作:查找、过滤、映射、归约
  4. 数据结构:栈、队列、双端队列
  5. 常用算法:二分查找、快速排序、去重
  6. 多维数组:创建和操作
  7. 性能优化:预分配、避免频繁插入

下一章,我们将学习表作为字典的高级用法。

最后更新:2026-03-27