jQuery / JavaScript JSON对象比较

有可能比较两组json对象的差异吗? 我所拥有的是一个通过jquery $ post()轮询JSON对象的脚本。 我想要做的是获取刚刚轮询的对象并将其与存储的对象进行比较。 如果从一个到另一个的任何变化将它们应用于存储的对象或替换它(以任何一种方式)但是从我正在使用的UI角度来看,通过找到它们之间的差异,无缝地将更改应用于JSON对象的用途。 2.我想这样做是因为我现在拥有它所以UI完全按照轮询重新加载,无论是否有变化,从UX角度来看基本上看起来像* *。

我想如果我能找到两个对象之间的差异,我会触发一个函数,我将编辑特定于差异的UI。

我想要做的是获取刚刚轮询的对象并将其与存储的对象进行比较。 如果从一个到另一个发生任何变化,则将它们应用于存储的对象或替换它(无论哪种方式)

如果您对一个非常简单的“它有任何变化吗?是/否”解决方案感到满意,如果它已经改变了,您只需用新的对象替换上一个对象(根据我引用的问题部分) ,然后您可以解析之前保存JSON响应, 即将其保存为Web服务器发送它的字符串格式。 然后,当下一个响应进来时,将新字符串与旧字符串进行比较。 如果它们不同(或者如果它是第一个请求),则解析JSON并根据需要对其进行处理以进行显示。 当然,这假设您的服务器端代码以一致的格式创建JSON字符串(而不是,例如,更改属性的顺序)。

如果我们假设你已经得到(解析)对象,那么isEqual(a,b)函数真的应该处理嵌套对象,属性是数组等。这可以递归地完成,只返回true或false,但是getDifferences(a,b)函数在报告嵌套对象中的差异时会变得混乱。 考虑这个简单的例子:

 old: {"mum" : "Maria", "dad" : "Pierre", "kids" : ["Joe", "Mike", "Louisa"] } new: {"mum" : "Julie", "dad" : "Pierre", "kids" : ["Joe", "Mary"] } 

差异是{"mum" : "Julie", "kids" : ["Mary"]} ? “妈妈”已经改变,“孩子”的名单已经改变,但是“迈克”改为“玛丽”,或者“迈克”和“路易莎”都和“玛丽”一起消失了,或者…… ? 也许它应该是"kids": ["Joe","Mary"]因为那是新的价值。 你如何表明删除? 这只是我头脑中的第一个例子,我不知道你将如何处理差异。 它可能很快变得更糟:如果“kids”数组包含对象而不是字符串来表示整个家族树怎么办? 如果新的“妈妈”财产是["Maria", "Julie"] (允许继父母等)怎么办?

如果对于您的特定数据,您知道您只有一维对象,那么您可以执行以下简单操作:

 function getDifferences(oldObj, newObj) { var diff = {}; for (var k in oldObj) { if (!(k in newObj)) diff[k] = undefined; // property gone so explicitly set it undefined else if (oldObj[k] !== newObj[k]) diff[k] = newObj[k]; // property in both but has changed } for (k in newObj) { if (!(k in oldObj)) diff[k] = newObj[k]; // property is new } return diff; } 

对上面允许嵌套对象的最简单的改变是假设如果一个属性是一个对象/数组,那么你只关心它是否有任何不同之处而不是深入报告确切地报告了哪些“子属性”已经改变。 如果是这样,只需采取上述function并更改:

 else if (oldObj[k] !== newObj[k]) 

 else if (!isEqual(oldObj[k],newObj[k])) 

其中isEqual()是浮动在Web或StackOverflow上的众多比较函数之一。

(注意:我没有上面的.hasOwnProperty() ,因为我假设作为JSON返回到Ajax请求的对象不会从原型链inheritance属性。类似地,为此目的的isEqual()函数不会需要担心属性是函数,只需要担心JSON字符串中的有效内容。)

很抱歉回答旧线程,但我的回答可能会帮助其他可能面临相同问题的人。最简单和最简单的代码来比较两个json对象,如下所示。 谢谢

  

一个可能的解决方案可能是使用jQuery的扩展。 只要对象具有相同的属性,就可以很好地完成。

 var newJSON = $.extend({},oldJSON,serverData); 

然后,您将保留旧对象,并使用旧对象中的任何属性创建一个新对象(如果它们不存在于新对象中),并使用服务器中新数据的属性覆盖任何现有属性。

 var objectsAreEqual = function(obj1, x){ var MAX_DEPTH = 10; var testEq = function(obj1, x, depth){ if(depth < MAX_DEPTH){ for (var p in obj1) { if(typeof(obj1[p]) !== typeof(x[p])) return false; if((obj1[p]===null) !== (x[p]===null)) return false; switch (typeof(obj1[p])) { case 'undefined': if (typeof(x[p]) != 'undefined') return false; break; case 'object': if(obj1[p]!==null && x[p]!==null && (obj1[p].constructor.toString() !== x[p].constructor.toString() || !testEq(obj1[p], x[p], depth + 1))) return false; break; case 'function': if (p != 'equals' && obj1[p].toString() != x[p].toString()) return false; break; default: if (obj1[p] !== x[p]) return false; } } } return true; }; // this is a little ugly, but the algorithm above fails the following: testEq([[1,2],[]], [[1,2],[1,3]], 0) return testEq(obj1, x, 0) && testEq(x, obj1, 0); };