使用 pairs 和 ipairs 遍历表
使用 pairs() 和 ipairs() 安全地遍历表。
使用 pairs 和 ipairs 遍历表 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
ipairs:有序遍历数组
ipairs(t) 会遍历从索引 1 开始的整数序列,并生成 (index, value) 键值对。它会在遇到第一个 nil 时停止。对于顺序很重要的类数组表,这是安全且可预测的选择。
local fruits = {"apple","banana","cherry"}
for i, fruit in ipairs(fruits) do
print(i, fruit)
end
-- 1 apple
-- 2 banana
-- 3 cherrypairs:遍历所有键
pairs(t) 会以未指定的顺序遍历表中每个非 nil 的键值对。它在内部使用 next() 函数。对于字典、混合表,或者需要访问所有类型的键时,请使用 pairs。
local info = {name="Lua", version=5.4, embedded=true}
for k, v in pairs(info) do
print(k, v)
end
-- name Lua
-- version 5.4
-- embedded true (order may vary)在 pairs 和 ipairs 之间进行选择
对于连续数组,请使用 ipairs(顺序有保证,遇到 nil 时停止)。对于字典、混合表,或者需要访问所有键时,请使用 pairs。对数组使用 pairs 虽然可行,但不保证顺序。对字典使用 ipairs 会遗漏非整数键。
local mixed = {10, 20, label="hello", 30}
-- ipairs: only sees 10, 20, 30 in order
for i, v in ipairs(mixed) do
io.write(v .. " ")
end
print() -- 10 20 30
-- pairs: sees everything
for k, v in pairs(mixed) do
print(k, v)
end统计元素数量
对于序列,#t 可以获取元素数量。对于字典,#t 不可靠——请使用 pairs 遍历并手动计数。这一区别非常重要,可以避免处理混合表或字符串键表时出现错误。
local arr = {10, 20, 30}
print("#arr:", #arr) -- 3 (reliable)
local dict = {a=1, b=2, c=3}
print("#dict:", #dict) -- 0 (unreliable for dicts!)
local count = 0
for _ in pairs(dict) do count = count + 1 end
print("count:", count) -- 3在遍历期间修改值
使用 pairs 遍历时,可以安全地更新现有键的值。但是,在遍历期间添加或移除键会产生未定义行为。请先收集要进行的更改,并在循环结束后应用。
local prices = {apple=1.0, banana=0.5, cherry=2.0}
-- Safe: update existing values
for k, v in pairs(prices) do
prices[k] = v * 1.1 -- 10% markup
end
for k, v in pairs(prices) do
print(k, string.format("%.2f", v))
end收集键
一个常见操作是将所有键收集到排序后的数组中,以生成确定性的输出。使用 pairs 收集键,然后使用 table.sort 对其排序。
local config = {host="localhost", port=8080, debug=true}
local keys = {}
for k in pairs(config) do
keys[#keys+1] = k
end
table.sort(keys)
for _, k in ipairs(keys) do
print(k, "=", config[k])
end
-- debug = true
-- host = localhost
-- port = 8080嵌套表遍历
对于嵌套表(由表组成的表),可以组合两个循环:外层循环遍历顶层,内层循环遍历每个嵌套表。结合递归,这种模式可以处理任意深度的嵌套。
local matrix = {
{1,2,3},
{4,5,6},
{7,8,9},
}
for i, row in ipairs(matrix) do
for j, val in ipairs(row) do
io.write(string.format("%3d", val))
end
print()
end使用 ipairs 进行筛选
使用 ipairs 遍历,并将通过谓词判断的元素追加到列表中,即可构建筛选后的列表。结果是一个只包含匹配元素的新数组。
local function filter(t, pred)
local result = {}
for _, v in ipairs(t) do
if pred(v) then result[#result+1] = v end
end
return result
end
local nums = {1,2,3,4,5,6,7,8,9,10}
local evens = filter(nums, function(n) return n % 2 == 0 end)
print(table.concat(evens, " ")) -- 2 4 6 8 10使用 ipairs 进行映射
对每个元素应用转换:遍历元素,并使用转换后的值构建新数组。这相当于函数式语言中的 map()。
local function map(t, fn)
local result = {}
for i, v in ipairs(t) do
result[i] = fn(v)
end
return result
end
local nums = {1, 2, 3, 4, 5}
local doubled = map(nums, function(n) return n * 2 end)
print(table.concat(doubled, " ")) -- 2 4 6 8 10
local words = {"hello","world"}
local upper = map(words, string.upper)
print(table.concat(upper, " ")) -- HELLO WORLD在自定义迭代器上使用 pairs
您可以让自定义对象具备可迭代能力:通过函数返回迭代器和状态。这种模式类似于 pairs 的内部工作方式:它返回 next, t, nil。您的迭代器工厂函数同样会返回一个函数以及可选的状态。
local function values(t)
local i = 0
return function()
i = i + 1
return t[i]
end
end
for v in values({"x","y","z"}) do
print(v)
end
-- x
-- y
-- z快速检查
关于 pairs() 和 ipairs(),以下哪项是正确的?
回顾:pairs 和 ipairs
总结:
ipairs:有序遍历从 1 开始的整数键,遇到 nil 时停止pairs:遍历所有键,顺序任意,不会提前停止- 字典使用
pairs;数组使用ipairs - 不要在 pairs 遍历过程中添加或移除键;更新现有值是安全的
- 收集并排序键,以生成确定性的输出
常见问题解答
「使用 pairs 和 ipairs 遍历表」课时是免费的吗?
是的 — 「使用 pairs 和 ipairs 遍历表」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「使用 pairs 和 ipairs 遍历表」这节课中我会学到什么?
使用 pairs() 和 ipairs() 安全地遍历表。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「使用 pairs 和 ipairs 遍历表」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。