使用 Lua 表解决 Python 代码片段的最佳方案

我正在学习 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!")
点赞
用户2616735
用户2616735

一对就像长度为2的列表,因此您可以简单地表示a如下所示:

a = {{1, 1}, {2, 2}, {3, 3}, {4, 4}}

这里的棘手部分是Python的in通过它们的_值_而不是_标识_来比较对象。也就是说,在Python中,(1, 2) in [(1, 2)](1, 2)不是(1, 2)

Lua没有“值”相等的概念(除了字符串和数字,它们没有标识)。

您可以通过设置__eq元方法来覆盖==的行为。不幸的是,Lua没有搜索表以查找与某个查询相等的值的函数,因此可能过度。

直接地,您可以编写一个“包含对”函数,该函数可以像下面定义的a一样工作:

function containsPair(list, pair)
    -- 找到带有与`pair`(作为对)相等的值的list的键
    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)
    -- 找到带有与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]为nil,但被要求。
            --让我们将其分配给默认值:
            self [k] = f()

            --并返回新的分配:
            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
2018-05-14 22:06:20