简体   繁体   中英

Objects deep/nested child-level comparison

I have two objects, I want to list changes between both as described below:

Currently I'm getting following output

current value || new value
title : Object 1 || title : Object 1 UPDATED
description : Object 1 Description || description : Object 1 Description UPDATED

Currently my code works for root level comparison(as highlighted above). But I am looking for comparisons on deep/nested child-level differences.

My output should look something like below

current value || new value
title : Object 1 || title : Object 1 UPDATED
description : Object 1 Description || description : Object 1 Description UPDATED
releations.tools[0].title : my first tool || releations.tools[0].title : my first tool UPDATED
relations.tools[0].types[1].name : test2 || DELETED
relations.training[0].description : training Description || relations.training[0].description : training Description UPDATED
relations.training[0].trainingTypes[1].name : in-person || DELETED

My current code

function diffObjects(obj1, obj2) {
    let res = [];
    let objKeysArray = _.keys(obj2) || [];
    if (!obj1 || !obj2) {
        return res;
    }
    if (objKeysArray.length === 0) {
       return res;
    }
    _(objKeysArray).forEach((key) => {
        console.log(obj1[key], obj2[key]);
        if (_.isArray(obj1[key]) && _.isArray(obj2[key])) {

        } else if (_.isObject(obj1[key]) && _.isObject(obj2[key])) {

        } else if (!_.isEqual(obj1[key], obj2[key])) {
            let change1 = `${key} : ${obj1[key]}`;
            let change2 = `${key} : ${obj2[key]}`;
            res.push({
                currentVal: change1,
                newVal: change2
            });
        }
    });
    return _.flattenDeep(res);
}

I have created a fiddle for above code here: JSFiddle Link : https://jsfiddle.net/vr0pgemj/

I have already referenced these posts:
Deep comparison of objects/arrays
Javascript Deep Comparison

But they only give me TRUE or FALSE results and not the differences I am looking for.

I made a working fork of your fiddle here with ECMAscript6 syntax.

Here is an embedded version as well:

 (function() { 'use strict'; function diffObj(obj1, obj2, ref) { var prefix = ref || ''; var res = []; if (!_.isUndefined(obj1) && _.isUndefined(obj2)) { res.push({ currentVal: prefix + ' : ' + JSON.stringify(obj1), newVal: 'DELETED' }); } else if (_.isUndefined(obj1) && !_.isUndefined(obj2)) { res.push({ currentVal: 'DELETED', newVal: prefix + ' : ' + JSON.stringify(obj2) }); } if (_.isUndefined(obj1) || _.isUndefined(obj2)) { return _.flattenDeep(res); } var keys = _.uniq(_.keys(obj1).concat(_.keys(obj2))); _(keys).forEach(function(key) { var value1 = obj1[key]; var value2 = obj2[key]; if (!_.isUndefined(value1) && _.isUndefined(value2)) { res.push({ currentVal: prefix + key + ' : ' + value1, newVal: 'DELETED' }); } else if (_.isUndefined(value1) && !_.isUndefined(value2)) { res.push({ currentVal: 'DELETED', newVal: prefix + key + ' : ' + value2 }); } else if (_.isArray(value1) && _.isArray(value2)) { var entries = Math.max(value1.length, value2.length); for (var i = 0; i < entries; i++) { res.push(diffObj(value1[i], value2[i], prefix + key + '[' + i + '].')); } } else if (_.isObject(value1) && _.isObject(value2)) { res.push(diffObj(value1, value2, prefix + key + '.')); } else if (!_.isEqual(value1, value2)) { res.push({ currentVal: prefix + key + ' : ' + value1, newVal: prefix + key + ' : ' + value2 }); } }); return _.flattenDeep(res); } var json1 = { "id": 1, "title": "Object 1", "description": "Object 1 Description", "test": "foo bar", "relations": { "tools": [{ "id": 2, "title": "my first tool", "description": "tools description", "types": [{ "id": 123, "name": "test" }, { "id": 111, "name": "test2" }] }], "training": [{ "id": 3, "title": "Test training", "description": "training Description", "trainingTypes": [{ "id": 1, "name": "online" }, { "id": 2, "name": "in-person" }, { "id": 3, "name": "boot camp" }] }] } }; var json2 = { "id": 1, "title": "Object 1 UPDATED", "description": "Object 1 Description UPDATED", "relations": { "tools": [{ "id": 2, "title": "my first tool UPDATED", "description": "tools description", "types": [{ "id": 123, "name": "test" }] }], "training": [{ "id": 3, "title": "Test training", "description": "training Description UPDATED", "trainingTypes": [{ "id": 1, "name": "online" }, { "id": 3, "name": "boot camp" }] }] } }; var res = diffObj(json1, json2); res = res.map(function(d) { return '<tr><td>' + d.currentVal + '</td><td>' + d.newVal + '</td></tr>'; }); $('#tableResult > tbody').append(res); })();
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script> <table id="tableResult" class="table table-hover table-striped"> <thead> <tr> <th> current </th> <th> new </th> </tr> </thead> <tbody> </tbody> </table>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM