我正在使用Lua编写的大量数据文件。他们中的大多数是用这种方式写的,一本电话簿"举个例子:
data = {
-- First Level - country
USA = {
-- Second level - city
Denver = {
-- Third level - actual entries
{name = 'John', number = '12345'},
-- more entries
},
Washington = {
{name = 'Ann', number = '54321'},
-- more entries
},
-- more cities with entries
},
-- more countries with cities and entries
}
因此,第一级是“国家/地区”的事实。第二个是城市'是隐式的,但它使数据更紧凑。
现在,在实际搜索某些数据时,我希望将这些数据作为条目进行迭代,包括这种水平的隐含信息。
-- Coroutine yielding entries including level data
function corIter(data)
for country,l1 in pairs(data) do
for city,l2 in pairs(l1) do
for _,entry in pairs(l2) do
-- Copy the entry
local out = {}
for k,v in pairs(entry) do
out[k] = v
end
-- Add level properties
out.country = country
out.city = city
coroutine.yield(out)
end
end
end
end
-- Iterate over the entries
local cor = coroutine.create(corIter)
local _, entry = coroutine.resume(cor, data)
while entry do
-- Handle the entry, has 'name', 'number', 'country' and 'city' keys
table.print(entry) -- (custom print function I use)
-- Get the next one
_, entry = coroutine.resume(cor)
end
但我认为这种方法可能很糟糕,因为它保持一个完整的线程只是为了以特定的方式迭代该死的表。
还有其他"显而易见的"解决这个问题?关键在于性能和易用性。我并不需要一个通用的解决方案(任意数量的"级别"内部数据表),但这一切都像黑客一样崩溃。
答案 0 :(得分:0)
local function phones(d)
local cn, c, tn, t, i
return
function()
local a
repeat
if tn then
a, i = t[i], i+1
if not a then
i, tn, t = 1, next(c, tn)
end
else
cn, c = next(d, cn)
i, tn, t = 1, next(c or {})
end
until a or not cn
return cn, tn, a
end
end
for country, town, abonent in phones(data) do
print(country, town, abonent.name, abonent.number)
end
答案 1 :(得分:0)
您可以在Lua中创建自己的自定义迭代器,无需使用协程。迭代器是调用时的函数,返回结构中的下一个元素(可以使用任何你想要的结构)。
您的示例的迭代器将是这样的:
JRTextExporterParameter.PAGE_HEIGHT
'corIter'返回的匿名函数将返回数据中的下一个元素。请注意,当我们使用'pairs'将条目复制到另一个表来迭代它们时,没有任何东西可以保证条目的顺序将保持原始顺序。
现在您可以使用此代码打印条目:
function corIter(data)
local itOut = {};
for country,l1 in pairs(data) do
for city,l2 in pairs(l1) do
for _,entry in pairs(l2) do
-- Copy the entry
local out = {}
for k,v in pairs(entry) do
out[k] = v
end
out.country = country
out.city = city
table.insert(itOut,out)
end
end
end
local i = 0
return function()
i = i + 1
return itOut[i]
end
end
end