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