场景:我想要一个比较两个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),返回的对象可能类似于:
compare(madrid, barca)
{"description" : "Bad", "trophies":[{"ucl":"3"}, {"copa":"5"}]};
或类似的东西,你就明白了。
有人知道解决方案吗?我已经找到了一个插件,但是我想知道是否还有其他选择。
可以使用通过对象键进行迭代的递归函数。然后使用Object.is测试NaN和null。然后测试如果第二对象是流延到该类型false喜欢0,NaN或null。列出两个对象的键并将它们连接起来以测试中缺少的键obj1,然后对其进行迭代。
NaN
null
false
0
obj1
当相同的键值之间存在差异时,它将存储的值object2并继续。如果两个键值都是对象,则意味着可以递归比较,因此也是如此。
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/