Lua数组

lua数组和普通的数组不同,需要好好看看,算是lua的重点,没一个小点都有对应的代码实践,建议跟着一起敲一遍这样理解会更好一点。主要就是什么是lua的数组以及关于lua数组的一些基础和常规操作,再就是对常见问题的解决。无他唯手熟尔。

一、什么是Lua数组?

Lua中并没有传统意义上的"数组"类型,数组实际上是通过table(表)实现的特殊数据结构 。更准确地说,Lua中的数组是以整数为键的有序table

复制代码
-- 这是一个Lua数组
local fruits = {"苹果", "香蕉", "橙子"}
print(fruits[1])  -- 输出:苹果

二、Lua数组的核心特性

1. 索引从1开始

复制代码
local numbers = {10, 20, 30, 40}
print(numbers[0])   -- 输出:nil
print(numbers[1])   -- 输出:10
print(numbers[2])   -- 输出:20

2. 长度操作符#

复制代码
local colors = {"红", "绿", "蓝"}
print(#colors)  -- 输出:3

-- 注意:长度操作符只对连续数组有效
local sparseArray = {[1] = "A", [3] = "C", [5] = "E"}
print(#sparseArray)  -- 输出可能为5,但行为不一致

三、数组基本操作

1. 创建与初始化

复制代码
-- 直接初始化
local emptyArray = {}
local primes = {2, 3, 5, 7, 11}

-- 动态创建
local squares = {}
for i = 1, 10 do
    squares[i] = i * i
end

2. 访问与修改

复制代码
local students = {"Alice", "Bob", "Charlie"}

-- 访问
print(students[2])  -- 输出:Bob

-- 修改
students[2] = "Bobby"
print(students[2])  -- 输出:Bobby

-- 添加元素
students[4] = "David"
print(#students)    -- 输出:4

3. 遍历数组

复制代码
local scores = {85, 92, 78, 95}

-- 方法1:使用数值for循环
for i = 1, #scores do
    print("学生" .. i .. "分数:" .. scores[i])
end

-- 方法2:使用ipairs迭代器(推荐)
for index, value in ipairs(scores) do
    print(index, value)
end

-- 方法3:通用pairs迭代器
for key, value in pairs(scores) do
    print(key, value)
end

四、数组实用操作

1. 数组拼接

复制代码
function concatArrays(arr1, arr2)
    local result = {}
    for i, v in ipairs(arr1) do
        result[i] = v
    end
    for i, v in ipairs(arr2) do
        result[#arr1 + i] = v
    end
    return result
end

local arr1 = {1, 2, 3}
local arr2 = {4, 5, 6}
local combined = concatArrays(arr1, arr2)

2. 数组切片

复制代码
function sliceArray(arr, startIndex, endIndex)
    local result = {}
    for i = startIndex, endIndex do
        result[#result + 1] = arr[i]
    end
    return result
end

local numbers = {1, 2, 3, 4, 5, 6}
local middle = sliceArray(numbers, 2, 4)
-- middle = {2, 3, 4}

3. 查找元素

复制代码
function findIndex(arr, value)
    for i, v in ipairs(arr) do
        if v == value then
            return i
        end
    end
    return nil
end

local fruits = {"apple", "banana", "orange"}
print(findIndex(fruits, "banana"))  -- 输出:2

五、多维数组

复制代码
-- 创建3x3矩阵
local matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
}

-- 访问元素
print(matrix[2][3])  -- 输出:6

-- 遍历多维数组
for i = 1, #matrix do
    for j = 1, #matrix[i] do
        io.write(matrix[i][j] .. " ")
    end
    print()
end

六、数组与table的混合使用

复制代码
-- 混合数据结构
local employee = {
    name = "张三",
    age = 28,
    skills = {"Lua", "Python", "C++"},  -- 数组部分
    projects = {                         -- 多维混合结构
        {name = "项目A", role = "开发"},
        {name = "项目B", role = "测试"}
    }
}

-- 访问混合结构
print(employee.name)                    -- 输出:张三
print(employee.skills[2])               -- 输出:Python
print(employee.projects[1].name)        -- 输出:项目A

七、性能优化与最佳实践

1. 避免创建稀疏数组

复制代码
-- 不推荐:稀疏数组
local badArray = {}
badArray[1] = "A"
badArray[1000] = "B"  -- 中间有大量nil值

-- 推荐:紧凑数组
local goodArray = {}
for i = 1, 1000 do
    goodArray[i] = "default"
end
goodArray[1000] = "B"

2. 使用table.concat进行字符串拼接

复制代码
local words = {"Hello", "World", "from", "Lua"}

-- 低效方式
local result = ""
for i, word in ipairs(words) do
    result = result .. word .. " "
end

-- 高效方式
local efficientResult = table.concat(words, " ")

3. 预分配数组大小(如果需要)

复制代码
local function createLargeArray(size)
    local arr = {}
    -- 预分配空间(Lua 5.3+)
    if math.tointeger then
        arr = table.new(size, 0)
    end
    for i = 1, size do
        arr[i] = i
    end
    return arr
end

八、实战示例:学生成绩管理系统

复制代码
local StudentManager = {}

function StudentManager.new()
    return {
        students = {},
        count = 0
    }
end

function StudentManager:addStudent(name, scores)
    self.count = self.count + 1
    self.students[self.count] = {
        id = self.count,
        name = name,
        scores = scores or {},
        average = 0
    }
    self:calculateAverage(self.count)
    return self.count
end

function StudentManager:calculateAverage(studentIndex)
    local student = self.students[studentIndex]
    if #student.scores > 0 then
        local total = 0
        for _, score in ipairs(student.scores) do
            total = total + score
        end
        student.average = total / #student.scores
    end
end

function StudentManager:getTopStudents(limit)
    -- 创建副本排序
    local sorted = {}
    for i = 1, self.count do
        sorted[i] = self.students[i]
    end
    
    table.sort(sorted, function(a, b)
        return a.average > b.average
    end)
    
    return sliceArray(sorted, 1, limit or 5)
end

-- 使用示例
local manager = StudentManager.new()
manager:addStudent("小明", {85, 90, 88})
manager:addStudent("小红", {92, 95, 89})
manager:addStudent("小刚", {78, 82, 80})

local topStudents = manager:getTopStudents(3)
for i, student in ipairs(topStudents) do
    print(string.format("%d. %s: %.2f", i, student.name, student.average))
end

九、常见问题与解决方案

Q1: 数组长度不准确?

复制代码
-- 问题:数组中有nil值
local problematic = {1, 2, nil, 4}
print(#problematic)  -- 输出可能是2或4

-- 解决方案:使用自定义长度函数
function safeLength(arr)
    local count = 0
    for _ in ipairs(arr) do
        count = count + 1
    end
    return count
end

Q2: 数组浅拷贝问题?

复制代码
local original = {{name = "test"}, {name = "demo"}}
local copy = {}

-- 错误方式:浅拷贝
for i, v in ipairs(original) do
    copy[i] = v  -- 只复制了引用!
end

-- 正确方式:深拷贝(简化版)
function deepCopyArray(arr)
    local result = {}
    for i, v in ipairs(arr) do
        if type(v) == "table" then
            result[i] = deepCopyArray(v)
        else
            result[i] = v
        end
    end
    return result
end

总结

Lua数组作为table的特殊应用,具有灵活、易用的特点。关键要点:

  1. Lua数组本质是索引为整数的table

  2. 索引从1开始,使用#获取长度

  3. 推荐使用ipairs进行遍历

  4. 避免稀疏数组以保持性能

  5. 利用table库函数简化操作

相关推荐
小李云雾20 小时前
FastAPI 后端开发:文件上传 + 表单提交
开发语言·python·lua·postman·fastapi
曼巴UE51 天前
Unlua 官方案例
c++·ue5·lua·ue
列星随旋2 天前
基于 Redis + Lua,实现“多维度原子限流”(令牌桶 + 滑动窗口)
java·redis·lua
上海合宙LuatOS2 天前
LuatOS扩展库API——【exgnss】GNSS定位
物联网·lua·luatos
0xDevNull2 天前
Redis Lua 脚本详细教程
redis·缓存·lua
上海合宙LuatOS2 天前
LuatOS扩展库API——【exlcd】显示屏控制
物联网·lua·luatos
0xDevNull2 天前
Spring Boot 中使用 Redis Lua 脚本详细教程
spring boot·redis·lua
DJ斯特拉4 天前
Redis使用lua脚本
junit·单元测试·lua
Aktx20FNz4 天前
OpenClaw中级到高级教程
lua
LcGero4 天前
Lua + Cocos Creator 实战:用 Lua 驱动 UI 与游戏逻辑
游戏·ui·lua