在Lua中,按顺序排列字符串键表的最佳方式



为了说清楚我想说的,我在这里举一个例子:

local exampleTable = {
["Key_A"] = {

},

["Key_B"] = {
},

["Key_D"] = {
},

当循环遍历这些时,并没有说它们会像代码中那样以相同的顺序出现。然而,我试图实现它看起来像在代码的相同顺序。独立于键的命名方式

我正在寻找一个更好的方法,为灵活性。如果还有更好的例子的话,那就比下面的好。

一个例子。

local differentExample = {
{"Key_A"},
{"Key_B"},
{"KEY_D"},
}

在这里,键使用数字作为它们的索引,与代码中的方式完全相同。您可以很容易地在表的内容之间添加任何其他内容,而不必担心顺序,因为它会自动为您索引,但作为一个数字。

我可以很容易地添加Key_C作为位置3:

local differentExample = {
{"Key_A"},
{"Key_B"},
{"Key_C"},
{"KEY_D"},
}

所以,我试着想出解决办法。

local differentExample = {
{
ID = "Key_A",
},

{
ID = "Key_B",
},

{
ID = "Key_D",
},
}

这里键确实是根据代码中的当前顺序按数字排序的。允许我添加"Key_C"中间画"Key_B"one_answers"Key_D">

这里的问题是,我不能很容易地索引这些键。我不得不循环遍历表中的所有条目,并按ID进行匹配。我不认为这是一个最优的解决方案。

然后是这个:

local differentExample = {
["Car"] = {
Order = 1
},
["Train"] = {
Order = 2
},
["Key_D"] = {
Order = 3
},
}

在这里,你可以知道它是什么顺序。在这里,如果你必须循环遍历它们,然后获取Order值,来设置某些东西的顺序,可能并不重要。

然而,这里的问题是,如果您想在条目之间添加一些东西,您将被迫手动编辑"Order">

local DominoStones = {
["DominoStone_A"] = {
Order = 1
},
["DominoStone_B"] = {
Order = 2
},
["DominoStone_D"] = {
Order = 3
},
}

如果我想在第一个顺序上添加一个字符串键,我最终不得不改变所有的&;order &;

local DominoStones = {
["DominoStone_Special"] = {
Order = 1
},

["DominoStone_A"] = {
Order = 1 -- I have to change this to 2
},
["DominoStone_B"] = {
Order = 2 -- I have to change this to 3
},
["DominoStone_D"] = {
Order = 3 -- I have to change this to 4
},
}

所以这是这个问题最糟糕的解决方案。

唯一的最佳解决方案,我知道,是这样的:

local orderedKeys = {
"Key_A",
"Key_B",
"Key_D"
}
local exampleTable = {
["Key_A"] = {
},
["Key_B"] = {
},
["Key_D"] = {
},
}

在这里,您可以使用orderedKeys来遍历字符串键。

然而,仍然不够完美,因为如果你想在exampleTable中添加一个新的字符串键,你也必须将它添加到orderedKeys表中。

所以还是不理想。

自定义打印表功能也不能解决这个问题,就像Garry's Mod或Roblox一样。他们使用桌子。Sort按字母顺序排序,然后打印出来,所以不要被它弄糊涂了。

所以我正在寻找更好的解决方案。更好的解决方案是什么?

我想出了一些东西:https://stackoverflow.com/a/72985494/11161500

我不确定这是否是最好的解决方案。

另一个解决方案:为自己编写一个实用程序来完成此操作!最简单的方法是用一个函数添加一个条目:

local order, map = {}, {}
local function add_entry(key, value)
table.insert(order, key)
map[key] = value
end
add_entry("KeyA", {})
add_entry("KeyB", {})
add_entry("KeyC", {})

或者如果你想让它更紧凑:

local function add_entries(key, value, ...)
if key == nil then return end
add_entry(key, value)
return add_entries(...)
end
add_entries("KeyA", {}, "KeyB", {}, "KeyC", {})

显然,如果你想要一个LISP-y的感觉,你也可以自己写一个实用程序来接受一个嵌套的表结构{{"KeyA", {}}, {"KeyB", {}}, {"KeyC", {}}(缺点:创建不必要的许多垃圾表)。

(有趣的事实:这是你通常如何初始化映射在Java中-通过调用put)

我刚刚想到的是:

local order = 0
function getOrder()
order += 1

return order
end
local exampleTable = {
["Key_A"] = {
Order = getOrder()
},
["Key_B"] = {
Order = getOrder()
},
["Key_D"] = {
Order = getOrder()
},
}

这确实设置了"Order"根据它在代码中的顺序。但我真的不确定这应该是多么理想。或者说它有多灵活。假设你想添加"Key_C"在中间"one_answers"Key_D",而代码本身已经在运行。

如果不重写整个表并将order重新初始化为0,就不会得到想要的结果。

相关内容

  • 没有找到相关文章

最新更新