我正在为我的问题寻找一个简单的解决方案。我有这个代码:
local Month = {
Jan = 1, Feb = 2, Mar = 3, Apr = 4,
May = 5, Jun = 6, Jul = 7, Aug = 8,
Sep = 9, Oct = 10, Nov = 11, Dec = 12
}
...
p.main = function()
local text = ""
for k,v in pairs(Month) do
text = text .. " " .. k;
end
return text;
end
Run Code Online (Sandbox Code Playgroud)
当我打电话时,p.main()我希望它Jan Feb ... Dec(按顺序)打印,尽管它打印Jan Mar Apr Oct Feb Dec Nov Aug Jul May Jun Sep在我看来是相当随机的顺序。
提前致谢!
Lua中表的哈希部分是无序的。字符串键位于哈希部分。这就是您观察“随机”顺序的原因。
只需将Month表从月份名称到数字的映射转换为从数字到名称的映射,即将其翻转并将其转换为列表:
local monthnames = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
Run Code Online (Sandbox Code Playgroud)
ipairs那么你可以方便地使用(而不是)按顺序迭代它pairs- 甚至更重要的是,你的p.main函数简化为对 的单个调用table.concat,这是一个用于连接字符串列表的 Lua 内置函数,并且由于该值是常量,因此你可以预先计算一下:
local space_separated_monthnames = table.concat(monthnames, " ")
function p.main()
return space_separated_monthnames
end
Run Code Online (Sandbox Code Playgroud)
这不会添加前导空格,但我认为无论如何都不是有意的。
如果您需要保留旧的查找,没问题 - 您可以从列表中生成它:
local monthnumber = {}
for i, name in ipairs(monthnames) do
monthnumber[name] = i
end
Run Code Online (Sandbox Code Playgroud)
另请注意,循环中的字符串连接是 Lua 中的反模式,因为它既效率低下(二次与线性,至少在构建更长的字符串时非常明显),又不方便编写(例如,您的代码发出可能不需要的前导空格)并且需要更多代码才能不发出它)。一般来说,如果您看到类似以下内容:
local str = vals[1]
for i = 2, #vals do
str = str .. separator .. vals[i]
end
Run Code Online (Sandbox Code Playgroud)
将其重构为
local str = table.concat(vals, separator)
Run Code Online (Sandbox Code Playgroud)
无论是为了性能还是可读性。