Подтвердить что ты не робот

Javascript JSON сравнение/diff?

Скажем, у меня есть следующие 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, мне нужно жестко закодировать в поле, которое я ищу... вот почему я ищу что-то меньшее от боли.

4b9b3361

Ответ 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;
};

Вы можете увидеть его в действии на этой демонстрационной странице.

Ответ 2

Вы можете посмотреть на json diff wrapper здесь

У него также есть демонстрационная страница. Вы можете использовать эту оболочку.

Ответ 3

Функция, именно то, что я получил, также полезна для сравнения объектов без JSON

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

Также расширена для глубоких вложенных объектов.

isEmpty 

можно сделать разными способами. см. Объект пуст?

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; 
}; 

Ответ 4

В ответе Питера Олсона он не будет проверять значения 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; 
    }; 

Ответ 5

Это решение не работает, если свойства obj2 равны свойствам obj1, но obj1 имеет больше свойств.