Skip to content

Instantly share code, notes, and snippets.

@bortunac
Last active January 3, 2018 07:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bortunac/1d48dcdc0df984ef2bac to your computer and use it in GitHub Desktop.
Save bortunac/1d48dcdc0df984ef2bac to your computer and use it in GitHub Desktop.
detect and react raw javascript object changes
gettype = function (x) {
return {}.toString.call(x).match(/\s([a-zA-Z]+)/)[1];
};
diff = function () {
this.comp=null; // comparation object
this.hnd=function(){}; // no function
};
diff.prototype = {
toString: function(){return "diff";},
analize: function (no, oo) {
this.old = oo;
this.now = no;
var rez = {};
(function (rez, no, oo) { // detect modifications or new properties
for (var v in no) {
if (oo[v] === undefined) {
rez[v] = 'add';
} else {
var type = gettype(no[v]);
if (
(type === 'String' || type === 'Number') && no[v] !== oo[v] // schimbare de valoare
||
gettype(oo[v]) !== gettype(no[v]) // schuimbare de tip
) {
rez[v] = 'mdf';
} else {
if(no[v] === oo[v])continue;
rez[v] = type === "Array" ? [] : {};
arguments.callee(rez[v], no[v], oo[v]);
}
}
}
})(rez, no, oo);
(function (rez, no, oo) { // detect deleted properties
for (var v in oo) {
var type = gettype(oo[v]);
if (no[v] === undefined) {
rez[v] = "del";
} else {
arguments.callee(rez[v], no[v], oo[v]);
}
}
})(rez, no, oo);
this.comp = rez;
return rez;
},
react: function (handler) {
var $ = this;
var poz=[];
(function (co, no, oo, level) {
for (var v in co) {
poz=poz.slice(0,level);
poz[level]=v;
if (typeof co[v] === 'string') {
// diff.hnd should be a function having context the hole diff object
// 1st param is the type of change add, del, mdf
// 2nd is a pointer array following diff.comp reading position
(handler||$.hnd).bind($)(co[v],poz);
}
else {
arguments.callee(co[v], no[v], oo[v] || {},level+1);
}
}
})(this.comp, this.now, this.old,0);
}
};
// object property pointer
// ex: o={a:{b:{c:[1,2]}}} addressing o.a.b.c[0] can be done like o.point(['a','b','c',0])
Object.defineProperty(Object.prototype,'point',{
value:function(arr){
var rez=this;
for(var s in arr){
rez=rez[arr[s]];
if(rez === undefined) {
return undefined;
}
}
return rez;
}
});
// require("diff"); or smth alike
// old object
var oo = {a: {p1:1,p2:2}, b: 1, d: {d1: [1, {aa: [[1, 4], 4, [33, 44]], bb: 22}], d2: 2},u:0};
// now object
var no = {a:{p1:2,p3:5}, c: 5, d: {d1: [2, {aa: {ww: 77}, cc: 33}]},u:0};
var df=new diff();
df.analize(no,oo);
df.react(function(type,pointer){
console.log(type,pointer,this.old.point(pointer),this.now.point(pointer));
});
@odragora
Copy link

Hi!

It's a great idea, but sadly I can't use this module to find changes between two arrays of objects in JSON notation.

image

P.S.: when I try to use your "example of use diff object" code it evaluates properly, but I can't do this with my JSON objects.

@canperk
Copy link

canperk commented Jan 3, 2018

I think it is crashing when comparing the arrays

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment