You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua 5.1中如何动态比较JSON转Lua表并列出差异?

通用Lua表差异对比方案(适配任意JSON转换结构)

直接上可复用的递归对比函数,Lua 5.1完全兼容,能自动遍历嵌套结构,把所有新增、删除、修改的差异按路径列出来:

function compareTables(old, new, path, diffs)
    path = path or ""
    diffs = diffs or {}

    -- 遍历旧表,找出删除或修改的项
    for k, v in pairs(old) do
        local currentPath = path ~= "" and path .. "." .. tostring(k) or tostring(k)
        local newVal = new[k]

        if newVal == nil then
            table.insert(diffs, string.format("删除: %s = %s", currentPath, tostring(v)))
        else
            -- 嵌套表递归对比,基础类型直接比较值
            if type(v) == "table" and type(newVal) == "table" then
                compareTables(v, newVal, currentPath, diffs)
            elseif v ~= newVal then
                table.insert(diffs, string.format("修改: %s 从 %s 变为 %s", currentPath, tostring(v), tostring(newVal)))
            end
        end
    end

    -- 遍历新表,找出新增的项
    for k, v in pairs(new) do
        local currentPath = path ~= "" and path .. "." .. tostring(k) or tostring(k)
        if old[k] == nil then
            table.insert(diffs, string.format("新增: %s = %s", currentPath, tostring(v)))
        end
    end

    return diffs
end

使用示例

假设你从API拿到的两个转换后表如下:

-- 旧API响应转换表
local oldData = {
    user = { id = 123, name = "Alice", age = 28 },
    posts = { { id = 1, title = "Old Post" }, { id = 2, title = "Second Post" } },
    status = "active"
}

-- 新API响应转换表
local newData = {
    user = { id = 123, name = "Alice", age = 29 },
    posts = { { id = 1, title = "Updated Post" }, { id = 3, title = "New Post" } },
    status = "active",
    email = "alice@example.com"
}

调用函数并打印结果:

local differences = compareTables(oldData, newData)
for _, diff in ipairs(differences) do
    print(diff)
end

输出结果:

修改: user.age 从 28 变为 29
修改: posts.1.title 从 Old Post 变为 Updated Post
删除: posts.2 = table: 0xXXXXXX
新增: posts.3 = table: 0xYYYYYY
新增: email = alice@example.com

细节优化(可选)

如果需要把嵌套表的内容展开显示,可加一个辅助函数:

function tableToString(t, indent)
    indent = indent or 0
    local str = "{"
    local first = true
    for k, v in pairs(t) do
        if not first then str = str .. ", " end
        first = false
        str = str .. "\n" .. string.rep("  ", indent+1)
        if type(k) == "string" then str = str .. k .. " = " end
        str = str .. (type(v) == "table" and tableToString(v, indent+1) or tostring(v))
    end
    str = str .. "\n" .. string.rep("  ", indent) .. "}"
    return str
end

把对比函数里的tostring(v)替换成tableToString(v),就能看到完整的嵌套表内容,可读性更强。

内容的提问来源于stack exchange,提问作者nodecentral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:35:19