使用C API循环遍历有序的lua表

4

考虑以下 Lua 表格:

foo = {
    bar1 = {a = 1, b = 2, c = "hello"},
    bar2 = {a = 5, b = 2, c = "bbq"},
    bar3 = {a = 76, b = 13, c = "pwnd"}
}

我正在尝试使用lua C API迭代此表以检索键名bar1、bar2和bar3。我使用了lua_next(L, -2)函数进行迭代,如许多人建议的那样,但问题是它返回的元素顺序是随机的。每次运行时顺序都会改变。

我使用以下代码:

for( lua_pushnil(L); lua_next(L, -2) != 0; lua_pop(L, 1) )
{
    printf("%s\n", lua_tostring(L, -2));
}

大多数情况下,输出是无序的,例如bar2 bar1 bar3。有时会有幸运的顺序。是否有一种简单的方法以有序方式循环表键?如果我使用有序的等效代码是什么?谢谢!
编辑:我知道我正在使用映射而不是数组。但在lua脚本中,我们有ipairs可以很好地解决这个问题。我正在寻找C API等效物。我已经找到了这个stackoverflow答案,它给出了一个不同的答案,但对我来说不起作用,所以我想知道那个答案是否好或相关。

3
这听起来像Lua在内部将键值对存储为哈希表。如果您想保持顺序,也许更好的解决方案是将bar条目存储为列表,而不是映射。 - Vite Falcon
3个回答

3

不行。Lua 遍历表的顺序是未定义的。

如果您知道键的格式为 barXXX,则可以动态创建这些键作为字符串并按照希望的顺序从表中获取相应的值。


2

将名称放入C数组中,然后在C中对它们进行排序。

正如其他人所说,表的哈希部分返回的键的顺序不能保证。

或者,使用类似数组的结构,以便您可以使用数组部分:

foo = {
  {name = 'bar1', a = 1,  b = 2,  c = "hello"},
  {name = 'bar2', a = 5,  b = 2,  c = "bbq"},
  {name = 'bar3', a = 76, b = 13, c = "pwnd"}
}

因此,您可以使用ipairs或等效的for i=1,#foo来按顺序迭代项。


1

查看Lua的文档,Lua支持的主要结构是哈希表。考虑到它总是会是一个哈希表,你可能想要重新实现foo作为一个数组。像这样,bar1bar2等可以成为数组的条目的一部分:

foo = {}
foo[0] = {name='bar1', ...}
foo[1] = {name='bar2', ...}
    ...

或者如@lhf所建议的那样,只需在for循环中构建“bar”名称(如果你知道它是有序的),并从“foo”表中检索值。

只是提醒一下,您在账户上链接的vizualize.me页面在Opera 26.0的“技能”部分存在一些格式问题。这是我能想到的最好的方式来让您知道:-)。 - MackM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接