主题
Table 表库使用说明
📖 模块概述
Table表库提供了操作LUA表的实用函数,包括插入、删除、排序、连接等操作。这些函数专门用于处理数组形式的表,是LUA编程中处理列表和数组数据的重要工具。
主要功能
- 📝 表元素插入和删除
- 🔄 表排序操作
- 🔗 表元素连接为字符串
- 📊 表长度获取
- 🎯 表元素移动和复制
适用场景
- 数组和列表操作
- 数据排序和搜索
- 字符串拼接
- 数据结构操作
- 算法实现
📚 API参考
📋 函数列表
| 函数名 | 功能描述 | 示例 |
|---|---|---|
➕ table.insert(list, [pos, value]) | 在表中插入元素 | table.insert(t, "a") |
➖ table.remove(list, [pos]) | 从表中删除元素 | table.remove(t, 1) |
🔄 table.sort(list, [comp]) | 对表进行排序 | table.sort(t) |
🔗 table.concat(list, [sep, start, end]) | 连接表元素为字符串 | table.concat(t, ",") |
📦 table.pack(...) | 打包参数为表 | table.pack(1, 2, 3) |
📦 table.unpack(list, [start, end]) | 解包表为参数 | table.unpack(t) |
🚚 table.move(a1, f, e, t, [a2]) | 移动表元素 | table.move(t1, 1, 3, 1, t2) |
➕ table.insert(list, [pos], value)
在表中插入元素
参数:
list(table): 目标表pos(number, 可选): 插入位置,默认为表末尾value(any): 要插入的值
返回值:
- 无返回值
示例:
lua
local fruits = {"苹果", "香蕉"}
-- 在末尾插入
table.insert(fruits, "橙子")
print(table.concat(fruits, ", ")) -- 苹果, 香蕉, 橙子
-- 在指定位置插入
table.insert(fruits, 2, "葡萄")
print(table.concat(fruits, ", ")) -- 苹果, 葡萄, 香蕉, 橙子
-- 在开头插入
table.insert(fruits, 1, "草莓")
print(table.concat(fruits, ", ")) -- 草莓, 苹果, 葡萄, 香蕉, 橙子实用例程
lua
--注:非有线网口发送数据,把网口网关清楚
--有符号数字转转无符号数字
function Unsigned(i,j) --i数值,j数据长度
if i<0 then
if j==16 or j==nil then k=i+65536 end
if j==32 then k=i+4294967296 end
else
k=i
end
return k
end
-- 创建一个队列
queue = {}
function enqueue(value) -- 入队操作
table.insert(queue, value)
end
function dequeue() -- 出队操作
if #queue > 0 then
return table.remove(queue, 1)
else
return nil -- 队列为空时返回nil
end
end
function peek() -- 查看队列首元素
if #queue > 0 then
return queue[1]
else
return nil -- 队列为空时返回nil
end
end把上面的地址、主题、引脚替换成你项目里的即可。
table.remove(list, [pos])
从表中删除元素
参数:
list(table): 目标表pos(number, 可选): 删除位置,默认为表末尾
返回值:
any: 被删除的元素
示例:
lua
local numbers = {1, 2, 3, 4, 5}
-- 删除末尾元素
local last = table.remove(numbers)
print("删除的元素:", last) -- 删除的元素: 5
print("剩余:", table.concat(numbers, ", ")) -- 剩余: 1, 2, 3, 4
-- 删除指定位置元素
local middle = table.remove(numbers, 2)
print("删除的元素:", middle) -- 删除的元素: 2
print("剩余:", table.concat(numbers, ", ")) -- 剩余: 1, 3, 4
-- 删除第一个元素
local first = table.remove(numbers, 1)
print("删除的元素:", first) -- 删除的元素: 1
print("剩余:", table.concat(numbers, ", ")) -- 剩余: 3, 4🔗 table.concat(list, [sep, start, end])
连接表元素为字符串
参数:
list(table): 要连接的表sep(string, 可选): 分隔符,默认为空字符串start(number, 可选): 起始索引,默认为1end(number, 可选): 结束索引,默认为表长度
返回值:
string: 连接后的字符串
示例:
lua
local words = {"Hello", "World", "from", "Lua"}
-- 基本连接
print(table.concat(words)) -- HelloWorldfromLua
-- 使用分隔符
print(table.concat(words, " ")) -- Hello World from Lua
print(table.concat(words, "-")) -- Hello-World-from-Lua
-- 指定范围
print(table.concat(words, " ", 1, 2)) -- Hello World
print(table.concat(words, " ", 2, 4)) -- World from Lua
-- 数字数组连接
local numbers = {1, 2, 3, 4, 5}
print(table.concat(numbers, ", ")) -- 1, 2, 3, 4, 5实用例程
lua
if j==32 then k=i+4294967296 end
else
k=i
end
return k
end
function byte2bin(n,m) --()16进制string转2进制指定位值
k=tonumber(n,16)
local j = {}
for i=7,0,-1 do
j[#j+1] = math.floor(k / 2^i)
k = k % 2^i
end
y=table.concat(j)
x=tonumber(string.sub(y,-m-1,-m-1))
return x
end
--CRC校验
function crc16(buf)
local init = 0xFFFF;
local poly = 0xA001;
local len=string.len(buf);
local ret = init;
local byte=0;
for j=1,len,1 do把上面的地址、主题、引脚替换成你项目里的即可。
🔄 table.sort(list, [comp])
对表进行排序
参数:
list(table): 要排序的表comp(function, 可选): 比较函数,默认为升序
返回值:
- 无返回值(原地排序)
示例:
lua
-- 数字排序
local numbers = {3, 1, 4, 1, 5, 9, 2, 6}
table.sort(numbers)
print("升序:", table.concat(numbers, ", ")) -- 升序: 1, 1, 2, 3, 4, 5, 6, 9
-- 降序排序
table.sort(numbers, function(a, b) return a > b end)
print("降序:", table.concat(numbers, ", ")) -- 降序: 9, 6, 5, 4, 3, 2, 1, 1
-- 字符串排序
local names = {"张三", "李四", "王五", "赵六"}
table.sort(names)
print("姓名排序:", table.concat(names, ", "))
-- 复杂对象排序
local students = {
{name = "张三", score = 85},
{name = "李四", score = 92},
{name = "王五", score = 78},
{name = "赵六", score = 96}
}
-- 按分数排序
table.sort(students, function(a, b) return a.score > b.score end)
print("按分数排序:")
for i, student in ipairs(students) do
print(string.format("%d. %s: %d分", i, student.name, student.score))
end📦 table.pack(...)
打包参数为表
参数:
...(any): 任意数量的参数
返回值:
table: 包含所有参数的表,带有n字段表示参数数量
示例:
lua
-- 打包多个参数
local packed = table.pack("a", "b", "c", nil, "e")
print("参数数量:", packed.n) -- 参数数量: 5
for i = 1, packed.n do
print(string.format("参数%d: %s", i, tostring(packed[i])))
end
-- 输出:
-- 参数1: a
-- 参数2: b
-- 参数3: c
-- 参数4: nil
-- 参数5: e
-- 函数参数打包
local function process_args(...)
local args = table.pack(...)
print("收到", args.n, "个参数")
for i = 1, args.n do
print(" 参数" .. i .. ":", args[i])
end
end
process_args(1, "hello", true, nil, 42)📦 table.unpack(list, [start, end])
解包表为多个返回值
参数:
list(table): 要解包的表start(number, 可选): 起始索引,默认为1end(number, 可选): 结束索引,默认为表长度
返回值:
any, ...: 表中的元素作为多个返回值
示例:
lua
-- 基本解包
local colors = {"红", "绿", "蓝"}
local r, g, b = table.unpack(colors)
print("颜色:", r, g, b) -- 颜色: 红 绿 蓝
-- 部分解包
local numbers = {1, 2, 3, 4, 5}
local first, second = table.unpack(numbers, 1, 2)
print("前两个:", first, second) -- 前两个: 1 2
-- 函数参数传递
local function sum(a, b, c)
return a + b + c
end
local values = {10, 20, 30}
local result = sum(table.unpack(values))
print("求和结果:", result) -- 求和结果: 60
-- 与table.pack配合使用
local function transform_args(...)
local args = table.pack(...)
-- 对每个参数加1
for i = 1, args.n do
if type(args[i]) == "number" then
args[i] = args[i] + 1
end
end
return table.unpack(args, 1, args.n)
end
local a, b, c = transform_args(1, 2, 3)
print("转换后:", a, b, c) -- 转换后: 2 3 4🚚 table.move(a1, f, e, t, [a2])
移动表元素
参数:
a1(table): 源表f(number): 源起始位置e(number): 源结束位置t(number): 目标起始位置a2(table, 可选): 目标表,默认为源表
返回值:
table: 目标表
示例:
lua
-- 表内移动
local arr = {1, 2, 3, 4, 5, 6, 7, 8}
print("原数组:", table.concat(arr, ", "))
-- 将位置2-4的元素移动到位置6开始
table.move(arr, 2, 4, 6)
print("移动后:", table.concat(arr, ", ")) -- 1, 2, 3, 4, 5, 2, 3, 4
-- 表间移动
local source = {"a", "b", "c", "d"}
local target = {"x", "y", "z"}
print("源表:", table.concat(source, ", "))
print("目标表:", table.concat(target, ", "))
-- 将源表的1-2位置元素移动到目标表的2位置开始
table.move(source, 1, 2, 2, target)
print("移动后目标表:", table.concat(target, ", ")) -- x, a, b
-- 数组复制
local original = {10, 20, 30, 40, 50}
local copy = {}
table.move(original, 1, #original, 1, copy)
print("原数组:", table.concat(original, ", "))
print("复制数组:", table.concat(copy, ", "))🚀 使用示例
示例1: 动态数组操作
lua
-- 动态数组操作示例
function dynamic_array_example()
print("=== 动态数组操作示例 ===")
-- 创建动态数组类
local DynamicArray = {}
DynamicArray.__index = DynamicArray
function DynamicArray:new()
local obj = {
data = {},
size = 0
}
setmetatable(obj, DynamicArray)
return obj
end
-- 添加元素
function DynamicArray:push(value)
self.size = self.size + 1
table.insert(self.data, value)
end
-- 删除末尾元素
function DynamicArray:pop()
if self.size > 0 then
self.size = self.size - 1
return table.remove(self.data)
end
return nil
end
-- 在指定位置插入
function DynamicArray:insert(index, value)
if index >= 1 and index <= self.size + 1 then
table.insert(self.data, index, value)
self.size = self.size + 1
return true
end
return false
end
-- 删除指定位置元素
function DynamicArray:remove(index)
if index >= 1 and index <= self.size then
local value = table.remove(self.data, index)
self.size = self.size - 1
return value
end
return nil
end
-- 获取元素
function DynamicArray:get(index)
if index >= 1 and index <= self.size then
return self.data[index]
end
return nil
end
-- 设置元素
function DynamicArray:set(index, value)
if index >= 1 and index <= self.size then
self.data[index] = value
return true
end
return false
end
-- 转换为字符串
function DynamicArray:toString()
return "[" .. table.concat(self.data, ", ", 1, self.size) .. "]"
end
-- 排序
function DynamicArray:sort(comp)
local temp = {}
table.move(self.data, 1, self.size, 1, temp)
table.sort(temp, comp)
table.move(temp, 1, self.size, 1, self.data)
end
-- 测试动态数组
local arr = DynamicArray:new()
print("创建空数组:", arr:toString())
-- 添加元素
arr:push(10)
arr:push(20)
arr:push(30)
print("添加元素后:", arr:toString())
-- 插入元素
arr:insert(2, 15)
print("插入15到位置2:", arr:toString())
-- 删除元素
local removed = arr:remove(3)
print("删除位置3的元素:", removed)
print("删除后:", arr:toString())
-- 修改元素
arr:set(1, 5)
print("修改位置1为5:", arr:toString())
-- 添加更多元素用于排序
arr:push(25)
arr:push(1)
arr:push(35)
print("添加更多元素:", arr:toString())
-- 排序
arr:sort()
print("升序排序后:", arr:toString())
arr:sort(function(a, b) return a > b end)
print("降序排序后:", arr:toString())
-- 弹出元素
while arr.size > 0 do
local value = arr:pop()
print("弹出:", value, "剩余:", arr:toString())
end
end
dynamic_array_example()示例2: 数据处理和统计
lua
-- 数据处理和统计示例
function data_processing_example()
print("\n=== 数据处理和统计示例 ===")
-- 模拟学生成绩数据
local students = {
{name = "张三", math = 85, english = 78, science = 92},
{name = "李四", math = 92, english = 88, science = 85},
{name = "王五", math = 78, english = 95, science = 89},
{name = "赵六", math = 96, english = 82, science = 94},
{name = "钱七", math = 88, english = 90, science = 87},
{name = "孙八", math = 75, english = 85, science = 91},
{name = "周九", math = 90, english = 79, science = 88},
{name = "吴十", math = 82, english = 93, science = 86}
}
-- 计算总分
for _, student in ipairs(students) do
student.total = student.math + student.english + student.science
student.average = student.total / 3
end
print("学生成绩统计:")
print(string.format("%-6s %4s %6s %6s %4s %6s",
"姓名", "数学", "英语", "科学", "总分", "平均"))
print(string.rep("-", 40))
for _, student in ipairs(students) do
print(string.format("%-6s %4d %6d %6d %4d %6.1f",
student.name, student.math, student.english,
student.science, student.total, student.average))
end
-- 按总分排序
table.sort(students, function(a, b) return a.total > b.total end)
print("\n按总分排名:")
for i, student in ipairs(students) do
print(string.format("%d. %s - 总分: %d, 平均: %.1f",
i, student.name, student.total, student.average))
end
-- 统计各科平均分
local subjects = {"math", "english", "science"}
local subject_names = {"数学", "英语", "科学"}
print("\n各科平均分:")
for i, subject in ipairs(subjects) do
local total = 0
local scores = {}
for _, student in ipairs(students) do
local score = student[subject]
total = total + score
table.insert(scores, score)
end
local average = total / #students
-- 排序计算中位数
table.sort(scores)
local median = scores[math.ceil(#scores / 2)]
-- 计算最高分和最低分
local max_score = scores[#scores]
local min_score = scores[1]
print(string.format("%s: 平均%.1f, 中位数%d, 最高%d, 最低%d",
subject_names[i], average, median, max_score, min_score))
end
-- 找出各科第一名
print("\n各科第一名:")
for i, subject in ipairs(subjects) do
local best_student = students[1]
for _, student in ipairs(students) do
if student[subject] > best_student[subject] then
best_student = student
end
end
print(string.format("%s: %s (%d分)",
subject_names[i], best_student.name, best_student[subject]))
end
-- 生成成绩分布
print("\n成绩分布 (按等级):")
local grade_ranges = {
{name = "优秀", min = 90, max = 100},
{name = "良好", min = 80, max = 89},
{name = "中等", min = 70, max = 79},
{name = "及格", min = 60, max = 69},
{name = "不及格", min = 0, max = 59}
}
for _, grade in ipairs(grade_ranges) do
local count = 0
local names = {}
for _, student in ipairs(students) do
if student.average >= grade.min and student.average <= grade.max then
count = count + 1
table.insert(names, student.name)
end
end
if count > 0 then
print(string.format("%s (%d-%d分): %d人 - %s",
grade.name, grade.min, grade.max, count,
table.concat(names, ", ")))
end
end
end
data_processing_example()示例3: 字符串处理工具
lua
-- 字符串处理工具示例
function string_processing_example()
print("\n=== 字符串处理工具示例 ===")
-- 字符串分割函数
local function split(str, delimiter)
local result = {}
local pattern = "([^" .. delimiter .. "]+)"
for match in str:gmatch(pattern) do
table.insert(result, match)
end
return result
end
-- 字符串连接函数(带格式化)
local function join_formatted(list, separator, formatter)
local formatted = {}
for i, item in ipairs(list) do
if formatter then
table.insert(formatted, formatter(item, i))
else
table.insert(formatted, tostring(item))
end
end
return table.concat(formatted, separator)
end
-- CSV数据处理
local csv_data = "张三,25,工程师,北京\n李四,30,设计师,上海\n王五,28,产品经理,深圳"
print("原始CSV数据:")
print(csv_data)
print()
-- 解析CSV
local lines = split(csv_data, "\n")
local records = {}
for _, line in ipairs(lines) do
local fields = split(line, ",")
table.insert(records, {
name = fields[1],
age = tonumber(fields[2]),
job = fields[3],
city = fields[4]
})
end
print("解析后的记录:")
for i, record in ipairs(records) do
print(string.format("%d. %s, %d岁, %s, %s",
i, record.name, record.age, record.job, record.city))
end
-- 按年龄排序
table.sort(records, function(a, b) return a.age < b.age end)
print("\n按年龄排序:")
local sorted_csv = join_formatted(records, "\n", function(record, index)
return string.format("%s,%d,%s,%s",
record.name, record.age, record.job, record.city)
end)
print(sorted_csv)
-- 生成HTML表格
print("\n生成HTML表格:")
local html_rows = {}
table.insert(html_rows, "<tr><th>姓名</th><th>年龄</th><th>职业</th><th>城市</th></tr>")
for _, record in ipairs(records) do
local row = string.format("<tr><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>",
record.name, record.age, record.job, record.city)
table.insert(html_rows, row)
end
local html_table = "<table>\n" .. table.concat(html_rows, "\n") .. "\n</table>"
print(html_table)
-- 文本统计
local text = "这是一个测试文本。文本包含多个句子。每个句子都有不同的长度。"
local sentences = split(text, "。")
print("\n文本统计:")
print("原文:", text)
print("句子数量:", #sentences)
local sentence_lengths = {}
for i, sentence in ipairs(sentences) do
if sentence ~= "" then
local length = string.len(sentence)
table.insert(sentence_lengths, length)
print(string.format("句子%d: \"%s\" (长度: %d)", i, sentence, length))
end
end
if #sentence_lengths > 0 then
table.sort(sentence_lengths)
local total_length = 0
for _, length in ipairs(sentence_lengths) do
total_length = total_length + length
end
print(string.format("平均句子长度: %.1f", total_length / #sentence_lengths))
print("最短句子长度:", sentence_lengths[1])
print("最长句子长度:", sentence_lengths[#sentence_lengths])
end
end
string_processing_example()示例4: 算法实现
lua
-- 算法实现示例
function algorithm_example()
print("\n=== 算法实现示例 ===")
-- 快速排序实现
local function quicksort(arr, low, high)
if low < high then
-- 分区操作
local function partition(arr, low, high)
local pivot = arr[high]
local i = low - 1
for j = low, high - 1 do
if arr[j] <= pivot then
i = i + 1
arr[i], arr[j] = arr[j], arr[i]
end
end
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
end
local pi = partition(arr, low, high)
quicksort(arr, low, pi - 1)
quicksort(arr, pi + 1, high)
end
end
-- 二分查找实现
local function binary_search(arr, target)
local left, right = 1, #arr
while left <= right do
local mid = math.floor((left + right) / 2)
if arr[mid] == target then
return mid
elseif arr[mid] < target then
left = mid + 1
else
right = mid - 1
end
end
return -1 -- 未找到
end
-- 测试快速排序
local test_array = {64, 34, 25, 12, 22, 11, 90, 88, 76, 50, 42}
print("原数组:", table.concat(test_array, ", "))
quicksort(test_array, 1, #test_array)
print("快排后:", table.concat(test_array, ", "))
-- 测试二分查找
local search_targets = {25, 50, 100, 11}
print("\n二分查找测试:")
for _, target in ipairs(search_targets) do
local index = binary_search(test_array, target)
if index > 0 then
print(string.format("找到 %d 在位置 %d", target, index))
else
print(string.format("未找到 %d", target))
end
end
-- 堆排序实现
local function heapify(arr, n, i)
local largest = i
local left = 2 * i
local right = 2 * i + 1
if left <= n and arr[left] > arr[largest] then
largest = left
end
if right <= n and arr[right] > arr[largest] then
largest = right
end
if largest ~= i then
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
end
end
local function heap_sort(arr)
local n = #arr
-- 构建最大堆
for i = math.floor(n / 2), 1, -1 do
heapify(arr, n, i)
end
-- 逐个提取元素
for i = n, 2, -1 do
arr[1], arr[i] = arr[i], arr[1]
heapify(arr, i - 1, 1)
end
end
-- 测试堆排序
local heap_test = {4, 10, 3, 5, 1, 8, 9, 2, 7, 6}
print("\n堆排序测试:")
print("原数组:", table.concat(heap_test, ", "))
heap_sort(heap_test)
print("堆排序后:", table.concat(heap_test, ", "))
-- 归并排序实现
local function merge_sort(arr)
if #arr <= 1 then
return arr
end
local mid = math.floor(#arr / 2)
local left = {}
local right = {}
table.move(arr, 1, mid, 1, left)
table.move(arr, mid + 1, #arr, 1, right)
left = merge_sort(left)
right = merge_sort(right)
-- 合并
local result = {}
local i, j = 1, 1
while i <= #left and j <= #right do
if left[i] <= right[j] then
table.insert(result, left[i])
i = i + 1
else
table.insert(result, right[j])
j = j + 1
end
end
while i <= #left do
table.insert(result, left[i])
i = i + 1
end
while j <= #right do
table.insert(result, right[j])
j = j + 1
end
return result
end
-- 测试归并排序
local merge_test = {38, 27, 43, 3, 9, 82, 10}
print("\n归并排序测试:")
print("原数组:", table.concat(merge_test, ", "))
local sorted = merge_sort(merge_test)
print("归并排序后:", table.concat(sorted, ", "))
-- 性能比较
print("\n排序算法性能比较:")
local function time_sort(sort_func, arr, name)
local start_time = os.clock()
sort_func(arr)
local end_time = os.clock()
return end_time - start_time
end
local large_array = {}
for i = 1, 1000 do
table.insert(large_array, math.random(1, 1000))
end
-- 复制数组用于不同算法测试
local arr1, arr2, arr3 = {}, {}, {}
table.move(large_array, 1, #large_array, 1, arr1)
table.move(large_array, 1, #large_array, 1, arr2)
table.move(large_array, 1, #large_array, 1, arr3)
local time1 = time_sort(function(arr) quicksort(arr, 1, #arr) end, arr1, "快速排序")
local time2 = time_sort(heap_sort, arr2, "堆排序")
local time3 = time_sort(table.sort, arr3, "内置排序")
print(string.format("快速排序: %.4f秒", time1))
print(string.format("堆排序: %.4f秒", time2))
print(string.format("内置排序: %.4f秒", time3))
end
algorithm_example()🔧 最佳实践
1. 高效的表操作
lua
-- 预分配表大小
local function create_large_array(size)
local arr = {}
-- 预分配数组部分
for i = 1, size do
arr[i] = 0
end
return arr
end
-- 批量操作
local function batch_insert(target, source, start_pos)
start_pos = start_pos or (#target + 1)
for i, value in ipairs(source) do
target[start_pos + i - 1] = value
end
end2. 内存友好的排序
lua
-- 原地排序,避免创建临时表
local function efficient_sort(arr, comp)
-- 使用内置排序,它是原地的
table.sort(arr, comp)
return arr
end
-- 稳定排序实现
local function stable_sort(arr, comp)
-- 添加原始索引保持稳定性
local indexed = {}
for i, v in ipairs(arr) do
indexed[i] = {value = v, index = i}
end
table.sort(indexed, function(a, b)
local result = comp(a.value, b.value)
if result == nil then
return a.index < b.index
end
return result
end)
-- 提取排序后的值
for i, item in ipairs(indexed) do
arr[i] = item.value
end
return arr
end3. 字符串连接优化
lua
-- 大量字符串连接的优化方法
local function efficient_string_join(strings, separator)
-- 对于大量字符串,table.concat比字符串连接更高效
return table.concat(strings, separator or "")
end
-- 构建器模式
local StringBuilder = {}
StringBuilder.__index = StringBuilder
function StringBuilder:new()
return setmetatable({parts = {}}, StringBuilder)
end
function StringBuilder:append(str)
table.insert(self.parts, tostring(str))
return self
end
function StringBuilder:toString(separator)
return table.concat(self.parts, separator or "")
end⚠️ 注意事项
1. 数组vs哈希表
table.insert/remove只适用于数组部分- 混合使用数组和哈希会影响性能
ipairs只遍历数组部分,pairs遍历所有元素
2. 排序注意事项
table.sort是不稳定排序- 比较函数必须满足严格弱序关系
- 排序是原地进行的,会修改原表
3. 性能考虑
- 频繁的
table.insert(arr, 1, value)性能较差 - 大表的
table.concat比字符串连接更高效 table.move比循环复制更快
4. 边界情况
- 空表的处理
- 索引越界检查
- nil值在数组中的处理
例程
表库(
table.*)用来组织「一组采样点、一批配置、一帧报文」这类列表数据,是工业脚本里用得最多的结构。下面例程都是可直接下载运行的完整脚本:顶层执行完即结束,不阻塞主循环。
例程 1:采集多点温度,拼成 CSV 一行
适用:全部机型 / 软PLC模拟器 / 上位机 | 依赖模块:table plc | 难度:★☆☆
场景:把一个通道的 8 个温度采样存进数组,最后拼成 25.6,26.1,... 这种 CSV 串上报或写文件。
完整代码(可直接下载运行):
lua
local temps = {}
for i = 1, 8 do
temps[i] = plc.df(100 + i - 1) -- 依次读 D100..D107 浮点
end
-- 转成字符串数组再 concat(concat 只接字符串)
local strs = {}
for i = 1, #temps do
strs[i] = string.format("%.1f", temps[i])
end
local csv = table.concat(strs, ",")
print("采样:", csv)要点:
table.insert(list, v)追加;已知下标时直接list[i] = v更快。table.concat(list, sep)把字符串数组拼成一串,比循环里..拼接高效得多。#list取数组长度(连续整数下标时准确)。
验证方法:
- 把 D100..D107 写成
25.6,26.1,...,运行打印「采样: 25.6,26.1,...」。 - 改成
for i = 1, 0空循环,#temps为 0,concat得到空串,不报错。
注意事项:
table.concat只接受字符串元素,传 number 会报错——先tostring/string.format。- 表里混了
nil(如list[3]=nil)会让#list长度判定失准,遍历用ipairs遇到nil会提前停。 - 稀疏表(不连续下标)别用
#,用pairs或自己记长度。
例程 2:对一批数据排序,取最大/最小
适用:同上 | 依赖模块:table | 难度:★☆☆
场景:一组成绩/温度要找最高最低、或按大小排好序再取中位数做滤波。
完整代码(可直接下载运行):
lua
local vals = { 23.1, 25.6, 22.0, 30.2, 24.8 }
table.sort(vals) -- 默认升序
print("最小", vals[1], "最大", vals[#vals])
-- 自定义:按绝对值排序
local mixed = { -3, 1, -5, 2 }
table.sort(mixed, function(a, b) return math.abs(a) < math.abs(b) end)
print(table.concat(mixed, ",")) -- 1,2,-3,-5要点:
table.sort(t)原地升序;table.sort(t, comp)传比较函数,返回a 应排在 b 前时为真。- 排完直接读
t[1](最小)和t[#t](最大)。 - 比较函数必须严格——
a==b时不要返回 true,否则排序行为未定义。
验证方法:
vals排序后打印「最小 22.0 最大 30.2」。mixed按绝对值排序打印1,2,-3,-5。
注意事项:
table.sort是原地排序,会改原表;想保留原顺序先table.move复制一份。- 比较函数写成
a <= b会在相等时返回 true,Lua 排序可能死循环或结果错;用<。 - 表里混
nil时排序结果不可预期,先清理。
例程 3:pack/unpack 与数组复制
适用:同上 | 依赖模块:table | 难度:★★☆
场景:写一个「接收任意多个通道值、统一处理」的函数(可变参数),以及把一份缓存数组复制给另一份再做处理。
完整代码(可直接下载运行):
lua
-- 可变参数打包成表:a 带长度字段 n
local a = table.pack(10, 20, 30)
print("收到", a.n, "个值") -- 3
-- 解包当参数传给函数
local function sum(x, y, z) return x + y + z end
print(sum(table.unpack(a))) -- 60
-- 复制数组:把 src 的 1..#src 搬到 dst 从 1 开始
local src = { 1, 2, 3, 4, 5 }
local dst = {}
table.move(src, 1, #src, 1, dst)
print(table.concat(dst, ",")) -- 1,2,3,4,5要点:
table.pack(...)把多值打成表,并带.n记录个数(区别于普通{...})。table.unpack(t, [i, j])把表还原成多值,可直接喂给多参函数。table.move(a, f, e, t, [a2])把a[f..e]搬到a2(默认同表)从t起。
验证方法:
- 打印「收到 3 个值」「60」「1,2,3,4,5」。
- 把
table.unpack(a)改成table.unpack(a, 1, 2),求和变30(只取前两个)。
注意事项:
table.pack的表有.n字段,但#a只数到最后一个非 nil 整数下标;迭代用for i=1,a.n最稳。unpack默认解包整张表,超大表可能触栈,必要时分批。table.move的t(目标起始)若与源区间重叠要小心方向,跨表复制(给a2)最安全。
最后更新: 2026-04-26版本: 1.0
函数速查表
下表列出本库全部函数与方法(含尚未单独成节的),点「说明」可跳转到对应小节。签名按通用记法:括号内按顺序列全参数,方括号里的可以省略(不传走默认值),... 表示还可继续传同类参数;h: 开头的是对象方法,先用库级函数拿回句柄再冒号调用。
| 方法与签名 | 作用 | 说明 |
|---|---|---|
table.concat(…) | 把数组元素用分隔符拼成一个字符串 | 本文开头 |
table.create(integer) | 预创建指定容量的空表(Lua 5.4) | 跳转 |
table.insert(integer, ...) | 向表插入元素(默认追加到末尾) | 本文开头 |
table.move(integer, integer, integer) | 在表之间搬移一段连续元素 | 本文开头 |
table.pack(...) | Pack/unpack | 本文开头 |
table.remove(…) | 移除并返回表中某个位置的元素 | 本文开头 |
table.sort(…) | 原地排序(可给比较函数) | 本文开头 |
table.unpack(…) | 把数组展开成多个返回值 | 本文开头 |
table.create
- 作用:预创建指定容量的空表(Lua 5.4)
- 调用形态:
table.create(integer)(库级函数) - 参数:1 个参数:第 1 个为整数(必填)
- 返回:1 个值
- 可用机型:软 PLC 模拟器 / 上位机