【问题标题】:Javascript JSON comparison/diff?Javascript JSON 比较/差异?
【发布时间】:2012-04-27 21:05:19
【问题描述】:

假设我有以下 2 个 json 对象:

JSON A:
{
"Field A":"1",
"Field B":"2",
"Field D":"Something",
"Field E":"6"
}

JSON B:
{
"Field A":"1",
"Field B":"2",
"Field C":"3",
"Field D":"Different"
}

示例功能: 函数 (jsonstringA, jsonstringB)

示例(如果使用 JSON A 和 JSON B 作为参数):

返回一个新的 JSON 对象,其中包含:

{
"Field C":"3", // because function sees jsonstringB had no "Field C"
"Field D": "Different" // sees jsonstringB had a different value for "Field D"
}

请注意,它使用 jsonstringA 作为比较的基础,因此该函数仅返回缺少的字段和 jsonStringB 的值。这就是为什么不返回“字段 E”及其值的原因。

如果可能的话,最好的方法是想出一个返回包含已更改值的 json 对象的函数?

我尝试过的: 我尝试通过手动指定要检查的字段来进行比较,但是我想要一些要求我不要对“字段”进行硬编码的东西,因为它的效率非常低,而且每次我向 JSON 添加新字段时B,我必须在我正在寻找的领域进行硬编码......这就是为什么我正在寻找不那么痛苦的东西。

【问题讨论】:

标签: javascript


【解决方案1】:

创建这样的函数并不难。只需遍历第二个对象中的每个字段,如果第一个对象中不存在或值与第一个对象不同,则将该字段放入返回对象中。

var compareJSON = function(obj1, obj2) {
  var ret = {};
  for(var i in obj2) {
    if(!obj1.hasOwnProperty(i) || obj2[i] !== obj1[i]) {
      ret[i] = obj2[i];
    }
  }
  return ret;
};

您可以在 this demo page 上看到它的实际效果。

【讨论】:

  • 啊,忽略我的评论,我假设他还想要对象 a 和 b 的可变数量属性的差异。但似乎两个对象具有相同数量的属性。
  • OP 可能想要递归到对象和数组值。
  • @Phrogz 我不确定,从他的描述和示例看来,浅比较就足够了。
  • 如果它可以通过数组值递归就好了,因为我很好奇,但是浅递归就足够了。谢谢,至少在我最终不得不处理数组之前,您帮助我摆脱了硬编码的混乱。
【解决方案2】:

你可以看看 json diff wrapper here

它也有演示页面。你可以使用这个包装器。

【讨论】:

    【解决方案3】:

    我所追求的函数也对非JSON对象比较有用

    http://jsfiddle.net/muJEu/11/

    还将它扩展到深层嵌套对象。

    isEmpty 
    

    可以通过多种方式完成。见Is object empty?

    var compareObj = function(obj1, obj2) { 
      var ret = {},rett; 
      for(var i in obj2) { 
          rett = {};  
          if (typeof obj2[i] === 'object'){
              rett = compareObj (obj1[i], obj2[i]) ;
              if (!isEmpty(rett) ){
               ret[i]= rett
              }              
           }else{
               if(!obj1 || !obj1.hasOwnProperty(i) || obj2[i] !== obj1[i]) { 
                  ret[i] = obj2[i]; 
          } 
       }
      } 
      return ret; 
    }; 
    

    【讨论】:

    • 如果一个值是一个数组,这将失败,因为typeof [] === 'object'
    • 如果属性存在于obj1 但不存在于obj2 中,则不会按预期执行。例如:a={a:true}b={b:true}compareObj(a,b) // returns {b:true}. you might expect {a:true,b:true}
    • rett 是在哪里定义的,还是全局变量?
    • rett 在第 2 行定义。 var ret= {}, rett;
    【解决方案4】:

    在 Peter Olson 的回答中,它不会检查 array 值,为了克服这个问题,我修改了这样的解决方案。

    var compareJSON = function(obj1, obj2) { 
          var ret = {}; 
          for(var i in obj2) { 
            if(!obj1.hasOwnProperty(i) || obj2[i] !== obj1[i]) {
              if(!Array.isArray(obj2[i]) || !(JSON.stringify(obj2[i]) == JSON.stringify(obj1[i]))){
              ret[i] = obj2[i];
              }
            } 
          } 
          return ret; 
        }; 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 2021-08-30
      • 2017-05-10
      相关资源
      最近更新 更多