javascript - 获取两个 json 对象的差异

标签 javascript jquery json diff

场景:我想要一个比较两个 JSON 对象的函数,并返回一个带有差异列表的 JSON 对象,如果可能的话,还需要更多数据,例如覆盖率指标。

var madrid = '{"type":"team","description":"Good","trophies":[{"ucl":"10"}, {"copa":"5"}]}';
var barca = '{"type":"team","description":"Bad","trophies":[{"ucl":"3"}]}';

如果我运行 compare(madrid, barca),返回的对象可能类似于:

{"description" : "Bad", "trophies":[{"ucl":"3"}, {"copa":"5"}]}; 

或者类似的东西,你懂的。

有人知道这个问题的解决方案吗?我已经找到了一个plugin ,但我想知道是否有其他选择。

最佳答案

可以使用通过对象键迭代的递归函数。然后使用 Object.is测试 NaNnull。然后测试第二个对象是否是转换为 false 的类型,例如 0NaNnull。 列出两个对象的键并将它们连接起来以测试 obj1 中缺少的键,然后对其进行迭代。

当相同键值有差异时,存储object2的值并继续。如果两个键值都是对象,则意味着可以递归比较,因此可以。

function diff(obj1, obj2) {
    const result = {};
    if (Object.is(obj1, obj2)) {
        return undefined;
    }
    if (!obj2 || typeof obj2 !== 'object') {
        return obj2;
    }
    Object.keys(obj1 || {}).concat(Object.keys(obj2 || {})).forEach(key => {
        if(obj2[key] !== obj1[key] && !Object.is(obj1[key], obj2[key])) {
            result[key] = obj2[key];
        }
        if(typeof obj2[key] === 'object' && typeof obj1[key] === 'object') {
            const value = diff(obj1[key], obj2[key]);
            if (value !== undefined) {
                result[key] = value;
            }
        }
    });
    return result;
}

上面的代码是 BSD 许可的,可以在任何地方使用。

测试链接:https://jsfiddle.net/gartz/vy9zaof2/54/

一个重要的观察,这会将数组转换为对象并比较相同索引位置的值。由于所需的额外复杂性,还有许多其他方法可以比较此函数未涵盖的数组。

编辑 2/15/2019:此答案已更改为添加新的 ES2017 语法并修复评论中的用例。


这只是一个开始,我还没有测试过,但我从一个过滤器或比较器函数开始,它是递归的,可以根据需要进行更改以获得优先结果。

function filter(obj1, obj2) {
    var result = {};
    for(key in obj1) {
        if(obj2[key] != obj1[key]) result[key] = obj2[key];
        if(typeof obj2[key] == 'array' && typeof obj1[key] == 'array') 
            result[key] = arguments.callee(obj1[key], obj2[key]);
        if(typeof obj2[key] == 'object' && typeof obj1[key] == 'object') 
            result[key] = arguments.callee(obj1[key], obj2[key]);
    }
    return result;
}

测试:http://jsfiddle.net/gartz/Q3BtG/2/

关于javascript - 获取两个 json 对象的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8431651/

相关文章:

jquery - 通过jquery访问tinymce iframe元素

php - 使用 jQuery、PHP 和 MySQL 为单选按钮加载 JSON 数据

javascript - 使用 jquery 更改纯 HTML Slider-Thumb 颜色(包括工作 css)

json - 配置 vscode json 格式化空间

json - Spring Web 服务和 Json

javascript - ASP.NET - 未捕获的语法错误 : Cannot use import statement outside a module

javascript - 使 Gulp 任务同步,而无需创建一堆其他任务

javascript - 如何在不拉伸(stretch) three.js 前景的情况下增加视角

javascript - 在图像右侧显示文本,就好像图像比实际大一样

php - 将连接结果映射为相关行下的数组