我学习Lua并且来自Python Lua表似乎相当复杂,下面的简单示例非常优雅但是将其转换为Lua对我来说很难,因为Lua没有元组概念。
所以我正在为这个片段寻找最好的Lua解决方案
a = [(1, 1), (2, 2), (3, 3), (4, 4)]
if (3, 3) in a:
print("Yay!")
else:
print("Nay!")
答案 0 :(得分:2)
一对就像长度为2的列表一样,所以你可以简单地将a
表示为
a = {{1, 1}, {2, 2}, {3, 3}, {4, 4}}
这里棘手的部分是Python in
通过值而不是身份来比较对象。也就是说,在Python中,(1,2) in [(1,2)]
只有(1,2) is not (1,2)
。
Lua没有"价值"平等(字符串和数字除外,它们没有身份)。
您可以通过设置==
metametod来覆盖__eq
的行为。遗憾的是,Lua没有搜索表等于某个查询值的函数,因此它可能有点过分。
直接地,你可以写一个"包含对"适用于上面定义的a
的函数,如下所示:
function containsPair(list, pair)
-- Find a key of list with a value equal to `pair` (as a pair)
for k, v in ipairs(list) do
if v[1] == pair[1] and v[2] == pair[2] then
return k
end
end
end
if containsPair(a, {3, 3}) then
......
end
您可以通过传递函数进行比较来使其更通用(或者等效地,只使用==
但实现__eq
元方法):
function containsLike(list, lhs, eq)
-- Find a key of list with a value equal to lhs
for k, lhs in ipairs(list) do
if eq(lhs, rhs) then
return k
end
end
end
function pairEq(a, b)
return a[1] == b[1] and a[2] == b[2]
end
if containsLike(list, {3, 3}, pairEq) then
......
end
如果您真正关注的是一组对,您可以使用"二维地图" (地图):
a = {}
a[1] = {}
a[1][1] = true
a[2] = {}
a[2][2] = true
a[3] = {}
a[3][3] = true
if a[3] and a[3][3] then
......
end
检查是否已创建行可能很麻烦。您可以使用元表来模仿Python的defaultdict
并清理它:
function default(f)
return setmetatable({}, {
__index = function(self, k)
-- self[k] is nil, but was asked for.
-- Let's assign it to the default value:
self[k] = f()
-- and return the new assignment:
return self[k]
end,
})
end
local a = default(function() return {} end)
a[1][1] = true
a[2][2] = true
a[3][3] = true
if a[3][3] then
......
end