我希望根据一组已知的默认值对 JSON 数据进行分类,从而降低对 JSON 数据的存储要求。基本上,我想要的是 jQuery 的 .extend()
函数的逆函数,这样可以通过任意 JSON 兼容对象的以下测试:
function test_delta(defaults, delta) {
var current = $.extend(true, {}, defaults, delta);
QUnit.same(get_delta(current, defaults), delta);
}
在我开始编写自己的 get_delta()
之前,有人知道现有的实现吗?
最佳答案
您真正要找的是对象差异(erential)算法。
不太难写-
function diff (obj1, obj2) {
var delta = {};
for (var x in obj1) {
if (obj2.hasOwnProperty(x)) {
if (typeof obj2[x] == "object") {
//recurse nested objects/arrays
delta[x] = diff(obj1[x], obj2[x]);
}
else {
//if obj2 doesn't match then - modified attribute
if (obj2[x] != obj1[x]) {
delta[x] = obj1[x];
}
}
}
else {
//obj2 doesn't have this - new attribute
delta[x] = obj1[x];
}
}
return delta;
}
alert(
JSON.stringify(
diff({ hello : 'world', gone : 'fishing' },
{ hello : 'world' })
)
);
//outputs:
{ gone : 'fishing' }
如您所见,这是一个非常基本的实现 - 您可以扩展它以通过在单独的对象中返回对 obj2 的添加来提供完整的差异。
此代码并非没有错误,对象原型(prototype)和函数在不同浏览器中的处理方式不同,但它应该足以作为数据结构的演示。
关于javascript - jQuery.extend(true, …) 的逆函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3410085/