这是一个涉及更复杂的比较方式的问题,因此它并不重复
我创建了一个JqTree,当用户更改其树形结构时,它们都是" old" JSON
和" new"应比较JSON
个结构,并且只应显示已更改的JSON
的值。
例如:
[{"name":"node1","id":1,"is_open":true,"children":
[
{"name":"child1","id":2},
{"name":"child2","id":3}
]
}]
客户将child1
置于child2
之后
[{"name":"node1","id":1,"is_open":true,"children":
[
{"name":"child2","id":3},
{"name":"child1","id":2}
]
}]
我只想比较它们并检查哪些值已更改并使用alert
显示它们,在这种情况下,它将是:
{"名称":"的child2"" ID":3},
{"名称":" child1"" ID":2}
到目前为止,我有这个比较它们的小代码:
JSON.stringify(object1) === JSON.stringify(object2); //我知道它不太可靠。
但是我正在寻找能够检查差异的东西"并从JSON中提取它。
提前致谢。
答案 0 :(得分:5)
你走了: rackspace
为您的无点击乐趣编辑版本:
// Call this function.
// The others are helpers for this one.
function getDiff(a, b){
var diff = (isArray(a) ? [] : {});
recursiveDiff(a, b, diff);
return diff;
}
function recursiveDiff(a, b, node){
var checked = [];
for(var prop in a){
if(typeof b[prop] == 'undefined'){
addNode(prop, '[[removed]]', node);
}
else if(JSON.stringify(a[prop]) != JSON.stringify(b[prop])){
// if value
if(typeof b[prop] != 'object' || b[prop] == null){
addNode(prop, b[prop], node);
}
else {
// if array
if(isArray(b[prop])){
addNode(prop, [], node);
recursiveDiff(a[prop], b[prop], node[prop]);
}
// if object
else {
addNode(prop, {}, node);
recursiveDiff(a[prop], b[prop], node[prop]);
}
}
}
}
}
function addNode(prop, value, parent){
parent[prop] = value;
}
function isArray(obj){
return (Object.prototype.toString.call(obj) === '[object Array]');
}
有关详细信息,请参阅上面的链接。有一条评论解释了我的一些假设。
这是如何使用递归来解决问题的示例。如果你不熟悉递归,我建议你做一些阅读。这是一篇关于它的SO文章: aws
注意:
像我一样使用JSON.stringify
并不是一个好主意。作为程序员,这对我来说很方便,因为我的程序可以“向前看”以查看每条路径是否有变化,但这需要付出代价。我已经遍历http://jsfiddle.net/musicin3d/cf5ddod1/3/来完成我的工作了,JSON.stringify
也遍历我每次调用它时发送的每个对象的树结构。在计算机科学中,我们称之为O(n!)的最坏情况,不太正式地称为“非常慢”。更好的设计只会遍历整个树,并跟踪它到达的位置。当它到达一个死胡同(称为“叶子”节点“)时,它将使用这些知识一次性地向diff
变量添加必要的数据结构。这将意味着我们的程序必须遍历整个数据结构,但我们的代码是唯一这样做的。所以每个节点只会被处理一次。
不过,这应该会让你知道其他人的建议。