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

Получение разницы двух json-объектов

Сценарий: мне нужна функция, которая сравнивает два объекта JSON и возвращает JSON-объект со списком различий и, если возможно, больше данных, таких как метрики покрытия.

var madrid = '{"type":"team","description":"Good","trophies":[{"ucl":"10"}, {"copa":"5"}]}';
var barca = '{"type":"team","description":"Bad","trophies":[{"ucl":"3"}]}';

Если я запустил compare(madrid, barca), возвращаемый объект мог выглядеть примерно так:

{"description" : "Bad", "trophies":[{"ucl":"3"}, {"copa":"5"}]}; 

Или что-то подобное, вы получаете идею.

Кто-нибудь знает о решении этого? Я уже нашел один плагин, но я хотел бы знать, есть ли какие-либо альтернативы.

4b9b3361

Ответ 1

Это просто начало, я не тестировал его, но начал с функции фильтра или компаратора, которая рекурсивна, измените ее, однако вам нужно получить приоритетные результаты.

function filter(obj1, obj2) {
    var result = {};
    for(key in obj1) {
        if(obj2[key] != obj1[key]) result[key] = obj2[key];
        if(typeof obj2[key] == 'array' && typeof obj1[key] == 'array') 
            result[key] = arguments.callee(obj1[key], obj2[key]);
        if(typeof obj2[key] == 'object' && typeof obj1[key] == 'object') 
            result[key] = arguments.callee(obj1[key], obj2[key]);
    }
    return result;
}

Тесты: http://jsfiddle.net/gartz/Q3BtG/2/

Ответ 2

Вы можете использовать rus-diff https://github.com/mirek/node-rus-diff, который создает совместимость с MongoDB (переименовать/отключить/установить):

// npm install rus-diff
var madrid = {"type":"team","description":"Good","trophies":[{"ucl":"10"}, {"copa":"5"}]};
var barca = {"type":"team","description":"Bad","trophies":[{"ucl":"3"}]};
var rusDiff = require('rus-diff').rusDiff
console.log(rusDiff(madrid, barca))

Выходы:

{ '$unset': { 'trophies.1': true },
  '$set': { description: 'Bad', 'trophies.0.ucl': '3' } }

Ответ 3

внес свои изменения в версию Габриэля Гарца. Этот режим работает в строгом режиме и удаляет проверку массива - всегда будет ложным. Он также удаляет пустые узлы из diff.

                //http://stackoverflow.com/info/679915/how-do-i-test-for-an-empty-javascript-object
                var isEmptyObject = function(obj) {
                    var name;
                    for (name in obj) {
                        return false;
                    }
                    return true;
                };

                //http://stackoverflow.com/info/8431651/getting-a-diff-of-two-json-objects
                var diff = function(obj1, obj2) {
                    var result = {};
                    var change;
                    for (var key in obj1) {
                        if (typeof obj2[key] == 'object' && typeof obj1[key] == 'object') {
                            change = diff(obj1[key], obj2[key]);
                            if (isEmptyObject(change) === false) {
                                result[key] = change;
                            }
                        }
                        else if (obj2[key] != obj1[key]) {
                            result[key] = obj2[key];
                        }
                    }
                    return result;
                };