如何遍历Lua中的表?
Posted
技术标签:
【中文标题】如何遍历Lua中的表?【英文标题】:How to iterate through table in Lua? 【发布时间】:2013-06-30 11:47:18 【问题描述】:所以,我有一个类似以下内容的表格:
arr =
apples = 'a', "red", 5 ,
oranges = 'o', "orange", 12 ,
pears = 'p', "green", 7
似乎无法根据索引访问它们,而值本身就是表,所以我只是将嵌套表的第一个值作为它的索引,所以现在看起来像这样:
arr =
apples = 0, 'a', "red", 5 ,
oranges = 1, 'o', "orange", 12 ,
pears = 2, 'p', "green", 7
所以,现在每当我使用这些表中的一个时,我都知道索引是什么,但仍然无法使用索引到达表,所以我开始编写一个循环遍历它们的函数,并检查索引,直到找到正确的索引。然后我意识到......如果我不能通过它们的索引引用它们,我该如何循环它们?所以,现在我被困住了。我真的很希望能够在大多数情况下输入 arr.apples 与 arr[1],但当然有时两者都需要。
【问题讨论】:
除非每个数组行之间有一个“,”,否则@greatwolf 的回答将失败。arr = apples = 0, 'a', "red", 5 , oranges = 1, 'o', "orange", 12 , pears = 2, 'p', "green", 7 ,
可以在以下位置看到一个工作示例:ideone.com/yWKHx7
@KjellHedström 我已经编辑了 OP 的问题并修复了一些小的语法错误。很好的收获。
【参考方案1】:
要遍历表中的所有键值对,您可以使用pairs
:
for k, v in pairs(arr) do
print(k, v[1], v[2], v[3])
end
输出:
pears 2 p green
apples 0 a red
oranges 1 o orange
编辑:请注意,Lua 不保证表的关联部分的任何迭代顺序。如果您想按特定顺序访问项目,请从 arr
检索密钥并对其进行排序。然后通过排序后的key访问arr
:
local ordered_keys =
for k in pairs(arr) do
table.insert(ordered_keys, k)
end
table.sort(ordered_keys)
for i = 1, #ordered_keys do
local k, v = ordered_keys[i], arr[ ordered_keys[i] ]
print(k, v[1], v[2], v[3])
end
输出:
apples a red 5
oranges o orange 12
pears p green 7
【讨论】:
刚刚注意到...为什么它以错误的顺序打印它们?如果它按顺序打印它们,我可以省略表中的索引变量,而只依靠它打印的顺序来查找索引,这会很好。 Lua 不保证表的关联部分的迭代顺序。 @Lemony 我添加了一个示例,说明如何以特定顺序遍历表。 @HenrikErlandsson - JSON 对象是无序的。请参阅spec。 当 Crockford 写道“一个对象是一组无序的名称/值对”时,他的意思是 JSON 字符串表示一个对象,其中包含不应依赖其顺序的对。然而 JSON 是一种文本交换格式,人们所说的“JSON 对象”实际上只是一个字符串,所以是的,它是有序的。我个人认为“JSON 对象”这个词被过度使用了。 Henrik 是正确的,有人想要按照 JSON 字符串中给出的顺序进行迭代的 idea 是有效的,但确实是“错误的”!【参考方案2】:如果您想通过多个键引用嵌套表,您可以将它们分配给单独的键。这些表没有重复,并且仍然引用相同的值。
arr =
apples = 'a', "red", 5
arr.apples = apples
arr[1] = apples
此代码块允许您遍历表中的所有键值对 (http://lua-users.org/wiki/TablesTutorial):
for k,v in pairs(t) do
print(k,v)
end
【讨论】:
【参考方案3】:对于那些想知道为什么 ipairs 不会一直打印表的所有值的人,这就是原因(我会对此发表评论,但我没有足够的好男孩点)。
ipairs 功能仅适用于键为 1 的元素的表。如果存在键为 1 的元素,ipairs 将按顺序尝试尽可能远, 1 -> 2 -> 3 -> 4 等等,直到它找不到具有序列中下一个键的元素。元素的顺序无关紧要。
不符合这些要求的表格将无法与 ipairs 一起使用,请改用 pairs。
例子:
ipairsCompatable = "AAA", "BBB", "CCC"
ipairsCompatable2 = [1] = "DDD", [2] = "EEE", [3] = "FFF"
ipairsCompatable3 = [3] = "work", [2] = "does", [1] = "this"
notIpairsCompatable = [2] = "this", [3] = "does", [4] = "not"
notIpairsCompatable2 = [2] = "this", [5] = "doesn't", [24] = "either"
ipairs 将尽可能地进行迭代,但不会迭代表中的任何其他元素。
kindofIpairsCompatable = [2] = 2, ["cool"] = "bro", [1] = 1, [3] = 3, [5] = 5
打印这些表格时,这些是输出。我还包含了 pairs 输出以供比较。
ipairs + ipairsCompatable
1 AAA
2 BBB
3 CCC
ipairs + ipairsCompatable2
1 DDD
2 EEE
3 FFF
ipairs + ipairsCompatable3
1 this
2 does
3 work
ipairs + notIpairsCompatable
pairs + notIpairsCompatable
2 this
3 does
4 not
ipairs + notIpairsCompatable2
pairs + notIpairsCompatable2
2 this
5 doesnt
24 either
ipairs + kindofIpairsCompatable
1 1
2 2
3 3
pairs + kindofIpairsCompatable
1 1
2 2
3 3
5 5
cool bro
【讨论】:
【参考方案4】:这里的所有答案都建议使用 ipairs,但请注意,它并非一直都有效。
t = [2] = 44, [4]=77, [6]=88
--This for loop prints the table
for key,value in next,t,nil do
print(key,value)
end
--This one does not print the table
for key,value in ipairs(t) do
print(key,value)
end
【讨论】:
为什么不一直打印? 我是 Lua 的初学者。我不知道。但是我在测试我的代码时遇到了这个问题。 @sgowd 为什么要在表 't' 之后添加 ',nil' - 这不是必需的。您还提到的问题(实际上不是问题)是 ipairs 返回一组基于整数的键。这意味着如果您的表具有基于字符串的键,则使用 ipairs 会将它们转换为整数键。文档非常清楚地描述了差异。 @SeniruPasan 感谢您提供关于不添加 ',nil' 的提示;我会试试看。在我给出的示例中,键是基于整数的键。 Baggef 的回答***.com/a/60088452/1566608 更清楚地说明了为什么 ipairs 不能一直工作。【参考方案5】:大家好,我是 LUA 的新手,但这些答案只帮助了我一半。所以我自己写。
for i in pairs(actions) do
if actions[i][3] ~= nill then
--do something
end
end
-
i - 是表中的值索引,类似于 c# 中的索引
操作 - 只是表的名称
actions[i][3] 如果第三个值不是 nil,它将检查表中的所有索引
【讨论】:
以上是关于如何遍历Lua中的表?的主要内容,如果未能解决你的问题,请参考以下文章