
正文
Lua Table pairs输出顺序问题 (版本差异 解决数字索引间断并兼容字符串索引)
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
问题标签:
Lua table pairs;Lua table 迭代器;Lua table 遍历顺序;Lua table 数字索引 字符串索引;
问题背景:
使用pairs输出table时,当一部分数字索引连续时,我们通常认为这一部分会按顺序遍历.
实际情况是在低版本Lua中不按顺序遍历,而高版本Lua中却会按顺序遍历.造成了版本差异,与通常认知不相符.
例如使用pairs输出如下table
T = {
[] = "",
[] = "",
[] = "",
[] = "",
[] = "", [] = "",
[] = "",
[] = "",
[] = "",
[] = "", [] = "",
[] = "",
[] = "",
q = "",
[] = "",
w = "",
[] = "",
e = "",
r = "",
t = "",
y = "",
}for k,v in pairs(T) do
print(k)
end
我们通常认为:输出结果会是先顺序输出12345,再乱序输出其它
但是恰巧 在lua 5.1.5 都是乱序

经测试在lua 5.1.5,如果想与通常认为相符,那么就不能显式指定索引值,只能隐式指定索引值,就是把上述table改成这样:
T = {
"",
"",
"",
"",
"", [] = "",
[] = "",
[] = "",
[] = "",
[] = "", [] = "",
[] = "",
[] = "",
q = "",
[] = "",
w = "",
[] = "",
e = "",
r = "",
t = "",
y = "",
}
但是这种解决办法,显然让人无法接受,让人窒息.所以今天研究了一下解决办法
目标:
使用迭代器输出Table时,首先顺序输出数字索引(允许数字索引间断),最后输出字符串索引
问题解决:
灵感来源于<Programming In Lua>中的代码:
function pairsByKeys(t)
local a = {} for n in pairs(t) do
a[#a + ] = n
end table.sort(a) local i = return function()
i = i +
return a[i], t[a[i]]
end
endfor key, value in pairsByKeys(表) do end
但是这个还差点意思,当table中包含字符串索引时,会报错.我们期望能和pairs一样兼容字符串索引.我们强化一下,如下:
function spairs(t)
local num_key_table = {}
local string_key_table = {} for k,v in pairs(t) do
if type(k) == "number" then
num_key_table[#num_key_table + ] = k
else
string_key_table[k] = v
end
end table.sort(num_key_table) local i = return function()
if i < #num_key_table then
i = i +
return num_key_table[i], t[num_key_table[i]]
else
for k,v in pairs(string_key_table) do
string_key_table[k] = nil
return k,v
end
end
end
endfor k,v in spairs(T) do
print(k)
end
5.27 修改:
function spairs(t)
local num_key_table = {}
local str_key_table = {}
for k,v in pairs(t) do
if type(k) == "number" then
num_key_table[#num_key_table + ] = k
else
str_key_table[#str_key_table + ] = k
end
end table.sort(num_key_table) local num_index =
local str_index =
return function()
if num_index < #num_key_table then
num_index = num_index +
return num_key_table[num_index], t[num_key_table[num_index]]
elseif str_index < #str_key_table then
str_index = str_index +
return str_key_table[str_index], t[str_key_table[str_index]]
end
end
end
对比:

还有改进的地方,欢迎指导







