是否可以比较2组json对象的差异?我所拥有的是一个通过jquery $ post()轮询JSON对象的脚本。我想要做的是拿走刚刚被轮询的对象,并将其与存储的对象进行比较。如果一个与另一个之间有任何更改,请将其应用于存储对象或替换(以任何一种方式替换),但是从UI角度来看,我正在通过查找两者之间的差异,将更改无缝地应用于JSON对象。 2.之所以要这样做,是因为现在我已经拥有了UI,因此无论更改是否更改,UI都将完全按每次轮询重新加载,从UX的角度来看,它基本上看起来像 __ 。
我想知道是否可以找到这两个对象之间的差异,然后我将触发一个功能,该功能将针对该差异进行编辑。
我想要做的是拿走刚刚被轮询的对象,并将其与存储的对象进行比较。如果一个与另一个之间有任何更改, 请将其 应用于存储的对象 或替换它(任一种方式)
如果您对真正简单的“是否以任何方式更改了?是/否”解决方案感到满意,那么如果更改了,只需将新的替换为先前的对象(根据我引用的问题的一部分) ,那么您可以 在 解析JSON响应 之前 将其保存,即,将其保存为Web服务器发送它的 字符串 格式。然后,在收到下一个响应时,将新字符串与旧字符串进行比较。如果它们不同(或者这是第一个请求),则解析JSON并对其进行处理以适当显示。自然地,这假设您的服务器端代码正在以一致的格式创建JSON字符串(而不是例如更改属性的顺序)。
如果我们假设您已经拥有(解析的)对象,则isEqual(a,b)函数确实应该处理嵌套的对象,数组的属性等。这可以递归完成,只需返回true或false,但是getDifferences(a,b)函数会引起混乱如何报告嵌套对象中的差异。考虑以下简单示例:
isEqual(a,b)
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"]因为这是新的价值。您如何指示删除?那只是我头上的第一个例子,我不知道您将如何处理差异。它可能很快变得更糟:如果“孩子”数组包含对象而不是字符串来表示整个家族树,该怎么办?如果新的“妈妈”属性是["Maria", "Julie"](允许继父母等)怎么办?
{"mum" : "Julie", "kids" : ["Mary"]}
"kids": ["Joe","Mary"]
["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; }
上面允许嵌套对象的最简单的更改是,仅假设如果属性是对象/数组,则您仅关心其是否在任何方面有所不同,而无需深入研究以准确报告更改了哪些“子属性” 。如果是这样,只需采用上述功能并更改:
else if (oldObj[k] !== newObj[k])
至
else if (!isEqual(oldObj[k],newObj[k]))
在isEqual()网上浮动的众多比较功能之一在哪里?
isEqual()
(注意:我并没有为.hasOwnProperty()上面的问题而烦恼,因为我假设以JSON形式返回到Ajax请求的对象将不会从原型链继承属性。类似地,isEqual()用于此目的的函数也不必担心属性是函数,则只需担心JSON字符串中的有效内容。)
.hasOwnProperty()