benjamine / jsondiffpatch

Diff & patch JavaScript objects
MIT License
4.83k stars 472 forks source link

Diff with Array of objects #80

Closed mayukhdas2k15 closed 9 years ago

mayukhdas2k15 commented 9 years ago

I have two arrays,

json1 = '[{"abc": "abc"}]';
json2 = '[{"bcd": "bcd"}, {"abc": "abc"}]';

I want to show the diff as only bcd is added, But after disabling the detectMove, I am getting the delta as

{"0":[{"bcd":"bcd"}],"1":[{"abc":"abc"}],"_t":"a","_0":[{"abc":"abc"},0,0]}

It seems that abc is treated as removed and then again added back in the delta. I was expecting only bcd should be there in the delta, how to interpret from this as only bcd has been added.

Have used the below:

var diffpatcher = jsondiffpatch.create({
    objectHash: function(obj) {
        return obj.id || obj.name;
    },
    arrays: {
        detectMove: false
    }
});

Is the objectHash correct in this case? Even if the object inside array is nested objects with multiple levels, then also I am not able to find the diff properly.

benjamine commented 9 years ago

right, the problem is those objects don't have id or name, so that objectHash is not matching anything. In other words, we need a way to tell that {"abc": "abc"} in json1 is {"abc": "abc"} in json2, and that is done by comparing the result of objectHashing them. Unfortunately determining when an object "is the same" as another, cannot be solved universally, that's why the objectHash function is needed (of course unless they are equal by reference which is always attempted before recurring to objectHash). An option that would work in your case is, for example:

    objectHash: function(obj) {
        return Object.keys(obj).join(',');
    },

or

    objectHash: function(obj) {
        return JSON.stringify(obj);
    },