我有一个分层嵌套的关联数组。它看起来像这样:
A = {
B = {
C = {},
D = {},
},
E = {
F = {
G = {}
}
},
H = {}
}
我想编写一个返回每个键的“祖先”的函数。
所以:
f("A") = {"A"}
f("B") = {"B","A"}
f("C") = {"C","B","A"}
f("G") = {"G","F","E","A"}
f("fake") = {}
我已经解决了我需要使用递归,但是我在编写函数时遇到了困难。有人可以给我一些关于如何编写这样一个函数的指示吗?
(请不要转介我http://xkcd.com/138/!)
答案 0 :(得分:6)
只需应用递归depth-first search即可找到您的特定元素并返回路径。
构造元素X
的路径的递归步骤。
X
:返回{X}
如果当前元素不是X
:
nil
。答案 1 :(得分:2)
A = {
B = {
C = {},
D = {},
},
E = {
F = {
G = {}
}
},
H = {}
}
function f(root, find)
-- iterate over all child values
for k, v in pairs(root) do
if k == find then
-- found the match
return({find})
else
-- no match, search the children
tmp = f(root[k], find)
if tmp ~= nil then
table.insert(tmp, 1, k)
return tmp
end
end
end
end
print(table.concat(f(A, "G"), " "))
由于您无法检索最高阶表的名称(在本例中为A),您可能需要将此表嵌套到另一个表中,如下例所示:
r = {A = {
B = {
C = {},
D = {},
},
E = {
F = {
G = {}
}
},
H = {}
}
}
在这种情况下,你需要调用f(r,“G”),原因。
答案 2 :(得分:1)
如果层次结构中存在循环,则需要跟踪已访问的子表。 请参阅globals code中的Lua live demo。
答案 3 :(得分:0)
这是我提出的使用Dario建议的解决方案:
function checkTable(t, key)
if t[key] then
return {key}
else
for k, subtable in pairs(t) do
local children = checkTable(subtable,key)
if #children ~= 0 then
table.insert(children,1,k)
return children
end
end
return {}
end
end