cancel
Showing results for 
Search instead for 
Did you mean: 

JSON Object Diff

kmiesse
Contributor

Is there a way to easily show what key values do not match between two JSON objects? If I have two objects with the same keys, can I output just the keys and values that do not match between the two objects? I am looking for a way to do this without having to create an equality expression for each key.

10 REPLIES 10

CMeyers
New Contributor II

I have code that can do this in javascript, although for arrays it is checking differences by index so you would need to be aware of that. I would think this code snippet could be adapted to run in a script snap and get the output you desire. I put in the two objects from your example into the little utility code I had and it found the differences, would just need to modify the output formatting to what you specified.

Function -

self.internalFindDifference = function(obj1, obj2, parent, accum) {
    var result = accum || { "changes": [] };
                
    for (key in obj1) {
        if (!obj2.hasOwnProperty(key)) {
            result.changes.push({ "field": parent ? parent + "." + key : key, "type": "add", "value": obj1[key] });                       
        } else if (!_.isEqual(obj1[key],obj2[key]) && typeof obj1[key] == 'object' && typeof obj2[key] == 'object') {
            var newParent = parent ? parent + "." + key : key;
            arguments.callee(obj1[key], obj2[key], newParent, result);
        } else if (!_.isEqual(obj1[key], obj2[key])) {
            result.changes.push({ "field": parent ? parent + "." + key : key, "type": "change", "fromValue": obj2[key], "toValue": obj1[key] });
        }
    }
                
    for (key in obj2) {
        if (!obj1.hasOwnProperty(key)) {
            result.changes.push({ "field": parent ? parent + "." + key : key, "type": "delete", "fromValue": obj2[key] });                        
        }
    }

    return result;
}

Example calling code -

var result = self.internalFindDifference(obj1, obj2, null, null);
Console.log(JSON.stringify(result, null, 4));

Thank you! I was hoping there was a way to do this without scripting since it seems like a common use case for SnapLogic but I will have to give it a try!

It is not a common usage. Deep level object nesting and comparison within those depths is a very uncommon scenario.

Well, how about just top-level comparison? If I had only one level, would that be easier?

I’m using this sort of as change data capture - I want to know the differences of unknown structures so I know what to change without having to know every field ahead of time and map it and then modify the pipeline every time there is a change in structure of the two objects to compare. Is this not something SnapLogic is meant to do? I’m honestly asking, not being combative.

Imran
New Contributor

@CMeyers can you share the pipeline