Generic deep diff between two objects

I have two objects: oldObj and newObj.

The data in oldObj was used to populate a form and newObj is the result of the user changing data in this form and submitting it.

Both objects are deep, ie. they have properties that are objects or arrays of objects etc – they can be n levels deep, thus the diff algorithm needs to be recursive.

Now I need to not just figure out what was changed (as in added/updated/deleted) from oldObj to newObj, but also how to best represent it.

So far my thoughts was to just build a genericDeepDiffBetweenObjects method that would return an object on the form {add:{...},upd:{...},del:{...}} but then I thought: somebody else must have needed this before.

So… does anyone know of a library or a piece of code that will do this and maybe have an even better way of representing the difference (in a way that is still JSON serializable)?

Update:

I have thought of a better way to represent the updated data, by using the same object structure as newObj, but turning all property values into objects on the form:

{type: '<update|create|delete>', data: <propertyValue>}

So if newObj.prop1 = 'new value' and oldObj.prop1 = 'old value' it would set returnObj.prop1 = {type: 'update', data: 'new value'}

Update 2:

It gets truely hairy when we get to properties that are arrays, since the array [1,2,3] should be counted as equal to [2,3,1], which is simple enough for arrays of value based types like string, int & bool, but gets really difficult to handle when it comes to arrays of reference types like objects and arrays.

Example arrays that should be found equal:

[1,[{c: 1},2,3],{a:'hey'}] and [{a:'hey'},1,[3,{c: 1},2]]

Not only is it quite complex to check for this type of deep value equality, but also to figure out a good way to represent the changes that might be.

25 Answers
25

Leave a Comment