一尘不染

jQuery / JavaScript JSON对象比较

json

是否可以比较2组json对象的差异?我所拥有的是一个通过jquery $
post()轮询JSON对象的脚本。我想要做的是拿走刚刚被轮询的对象,并将其与存储的对象进行比较。如果一个与另一个之间有任何更改,请将其应用于存储对象或替换(以任何一种方式替换),但是从UI角度来看,我正在通过查找两者之间的差异,将更改无缝地应用于JSON对象。
2.之所以要这样做,是因为现在我已经拥有了UI,因此无论更改是否更改,UI都将完全按每次轮询重新加载,从UX的角度来看,它基本上看起来像 __

我想知道是否可以找到这两个对象之间的差异,然后我将触发一个功能,该功能将针对该差异进行编辑。


阅读 584

收藏
2020-07-27

共1个答案

一尘不染

我想要做的是拿走刚刚被轮询的对象,并将其与存储的对象进行比较。如果一个与另一个之间有任何更改, 请将其 应用于存储的对象
或替换它(任一种方式)

如果您对真正简单的“是否以任何方式更改了?是/否”解决方案感到满意,那么如果更改了,只需将新的替换为先前的对象(根据我引用的问题的一部分) ,那么您可以
解析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"]因为这是新的价值。您如何指示删除?那只是我头上的第一个例子,我不知道您将如何处理差异。它可能很快变得更糟:如果“孩子”数组包含对象而不是字符串来表示整个家族树,该怎么办?如果新的“妈妈”属性是["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()网上浮动的众多比较功能之一在哪里?

(注意:我并没有为.hasOwnProperty()上面的问题而烦恼,因为我假设以JSON形式返回到Ajax请求的对象将不会从原型链继承属性。类似地,isEqual()用于此目的的函数也不必担心属性是函数,则只需担心JSON字符串中的有效内容。)

2020-07-27