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
相关产品推荐
相关产品推荐

