在Lua中,没有指定对迭代通过键的顺序。但是,您可以保存在阵列样式表中添加项目的顺序,并使用ipairs
(它具有用于迭代数组中键的已定义顺序)。为了解决这个问题,您可以使用元表创建自己的有序表,以便在添加新键时保持键顺序。
编辑(前面的代码插在更新密钥的多个副本)
要做到这一点,你可以使用__newindex
,我们可以,只要指数没有被添加到表中调用。 ordered_add
方法更新,删除或将密钥存储在隐藏表_keys
和_values
中。请注意,当我们更新密钥时,我们始终会调用__newindex
,因为我们没有将该值存储在表中,而是将其存储在“隐藏”表_keys
和_values
中。然而
需要注意的是,我们不能在此表中使用任何键,键名"_keys"
将覆盖我们隐藏的表,以便在更安全的替代是使用ordered_table.insert(t, key, value)
ordered_table.index(t, key)
和ordered_table.remove(t, key)
方法。
ordered_table = {}
function ordered_table.insert(t, k, v)
if not rawget(t._values, k) then -- new key
t._keys[#t._keys + 1] = k
end
if v == nil then -- delete key too.
ordered_table.remove(t, k)
else -- update/store value
t._values[k] = v
end
end
local function find(t, value)
for i,v in ipairs(t) do
if v == value then
return i
end
end
end
function ordered_table.remove(t, k)
local v = t._values[k]
if v ~= nil then
table.remove(t._keys, find(t._keys, k))
t._values[k] = nil
end
return v
end
function ordered_table.index(t, k)
return rawget(t._values, k)
end
function ordered_table.pairs(t)
local i = 0
return function()
i = i + 1
local key = t._keys[i]
if key ~= nil then
return key, t._values[key]
end
end
end
function ordered_table.new(init)
init = init or {}
local t = {_keys={}, _values={}}
local n = #init
if n % 2 ~= 0 then
error"in ordered_table initialization: key is missing value"
end
for i=1,n/2 do
local k = init[i * 2 - 1]
local v = init[i * 2]
if t._values[k] ~= nil then
error("duplicate key:"..k)
end
t._keys[#t._keys + 1] = k
t._values[k] = v
end
return setmetatable(t,
{__newindex=ordered_table.insert,
__len=function(t) return #t._keys end,
__pairs=ordered_table.pairs,
__index=t._values
})
end
--- Example Usage:
local t = ordered_table.new{
"hello", 1, -- key, value pairs
2, 2,
50, 3,
"bye", 4,
200, 5
}
print(#t)
print("hello is", t.hello)
print()
for k, v in pairs(t) do --- Lua 5.2 __pairs metamethod
print(k, v)
end
t.bye = nil -- delete that
t[2] = 7 -- use integer keys
print(#t)
这些值是您想要循环的顺序吗?或者这只是巧合吗? –
我想按照它写入的顺序循环显示表“tbl”,所以第一次通过应该是关键“你好”,第二个2,第三个50,... –
根据内部源代码的顺序,稍后再询问问题当没有意识到这个订单的人因某种原因重新安排事情时。如果您需要明确的订单,请明确订单。 –