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库函数简化操作

相关推荐
每天回答3个问题18 小时前
Lua 字符串
ue4·lua
Wang's Blog2 天前
Lua: 基于协程的生产者-消费者模型实现
开发语言·lua
Wang's Blog2 天前
Lua: 协程编程详解之从基础到多任务处理与应用实战
开发语言·lua
I小码哥2 天前
Windows 安装 Chocolatey 包管理器
lua
I小码哥2 天前
无法使用lua.exe
lua
Wang's Blog3 天前
Lua: 元表机制实现运算符重载与自定义数据类型
开发语言·lua
Wang's Blog3 天前
Lua: 面向对象编程详解之类、继承、封装与多态实现
lua
Wang's Blog4 天前
Lua: 核心机制解析之函数的多维魔法与模块化封装艺术
开发语言·lua
Macbethad5 天前
自动化测试技术报告
开发语言·lua