如何仅从两个JSON对象获取“已更改”值

这是一个涉及更复杂的比较方式的问题,因此它不是重复的

我创建了一个JqTree ,当用户更改其树结构时,应该比较“旧” JSON和“新” 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中提取它的东西。

提前致谢。

你去了: http : //jsfiddle.net/musicin3d/cf5ddod1/3/

编辑版本以获得无需点击的乐趣:

 // 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文章: 什么是递归,什么时候应该使用它?

值得注意的是
像我一样使用JSON.stringify不是一个好主意。 作为程序员,这对我来说很方便,因为我的程序可以“向前看”以查看每条路径是否有变化,但这需要付出代价。 我已经遍历了树结构来完成我的工作, JSON.stringify 遍历每次调用它时发送的每个对象的树结构。 在计算机科学中,我们称之为O(n n )的最坏情况,不太正式地称为“非常慢”。 更好的设计只会遍历整个树,并跟踪它到达的位置。 当它到达一个死胡同(称为“叶子”节点“)时,它将使用这些知识一次性将所需的数据结构添加到diff变量。这意味着我们的程序必须遍历整个数据结构,但是我们的代码是唯一这样做的。所以每个节点只会被处理一次。

不过,这应该可以让你了解别人的建议。