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的特殊应用,具有灵活、易用的特点。关键要点:
-
Lua数组本质是索引为整数的table
-
索引从1开始,使用
#获取长度 -
推荐使用
ipairs进行遍历 -
避免稀疏数组以保持性能
-
利用table库函数简化操作