Skip to content

Instantly share code, notes, and snippets.

@myobie
Created August 3, 2010 17:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save myobie/506740 to your computer and use it in GitHub Desktop.
Save myobie/506740 to your computer and use it in GitHub Desktop.
var DiffJSON = (function() {
var isObject = function(obj) {
return Object.prototype.toString.apply(obj) == "[object Object]";
};
var retrieve = function(nested_key) {
var keys = nested_key.split("."), current_object = this;
for (var i = 0; i < keys.length; i++) { current_object = current_object[keys[i]] }
return current_object;
};
var changed_objects = function(what) {
var objs = [];
for (var i=0; i < this.diff.changed[what].length; i++) {
var o = this.diff.retrieve(this.diff.changed[what][i]);
o.name = this.diff.changed[what][i];
objs.push(o);
}
return objs;
};
var check = function(neue, original, namespace) {
var removed = [], added = [], modified = [], all = [], result = {};
if (typeof namespace != "string") { namespace = ""; }
for (var element in neue) {
if (typeof original[element] == "undefined") {
added.push(namespace + element);
all.push(namespace + element);
result[element] = { change: "+", neue: neue[element], original: undefined };
} else if (original[element] != neue[element] && !(isObject(original[element]) && isObject(neue[element]))) {
modified.push(namespace + element);
all.push(namespace + element);
result[element] = { change: "/", neue: neue[element], original: original[element] };
} else if (isObject(original[element]) && isObject(neue[element])) {
result[element] = check(neue[element], original[element], namespace+element+".");
removed = removed.concat(result[element].diff.changed.removed);
added = added.concat(result[element].diff.changed.added);
modified = modified.concat(result[element].diff.changed.modified);
all = all.concat(result[element].diff.changed.all);
delete result[element].diff;
} else {
result[element] = original[element];
}
}
for (var element in original) {
if (typeof neue[element] == "undefined") {
removed.push(namespace + element);
all.push(namespace + element);
result[element] = { change: "-", neue: undefined, original: original[element] };
}
}
result.diff = {
changed: { removed:removed, added:added, modified:modified, all:all },
original: original,
neue: neue,
retrieve: function(what) { return retrieve.apply(result, [what]); }
};
removed.objects = function() { return changed_objects.apply(result, ["removed"]); };
added.objects = function() { return changed_objects.apply(result, ["added"]); };
modified.objects = function() { return changed_objects.apply(result, ["modified"]); };
all.objects = function() { return changed_objects.apply(result, ["all"]); };
return result;
};
return check;
})();
{
"name":"Nathan Herald",
"age":{
"change":"/",
"neue":26,
"original":25
},
"pets":{
"dog":{
"name":{
"change":"+",
"neue":"Fred"
},
"legs":4
},
"cat":{
"change":"-",
"original":{
"name":"Charles",
"legs":4
}
}
},
"hat":{
"change":"+",
"neue":{
"type":"Baseball Cap",
"color":"White",
"hex_color":"#eee"
}
},
"diff":{
"changed":{
"removed":["pets.cat"],
"added":["pets.dog.name",
"hat"],
"modified":["age"],
"all":["age",
"pets.dog.name",
"pets.cat",
"hat"]
},
"original":{
"name":"Nathan Herald",
"age":25,
"pets":{
"dog":{
"legs":4
},
"cat":{
"name":"Charles",
"legs":4
}
}
},
"neue":{
"name":"Nathan Herald",
"age":26,
"pets":{
"dog":{
"name":"Fred",
"legs":4
}
},
"hat":{
"type":"Baseball Cap",
"color":"White",
"hex_color":"#eee"
}
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>Test of diff-json.js</title>
</head>
<body>
<pre id="output"></pre>
<script type="text/javascript" src="http://www.JSON.org/json2.js"></script>
<script type="text/javascript" src="diff-json.js"></script>
<script type="text/javascript">
var o = {
name: "Nathan Herald",
age: 25,
pets: {
dog: {
legs: 4
},
cat: {
name: "Charles",
legs: 4
}
}
}
var n = {
name: "Nathan Herald",
age: 26,
pets: {
dog: {
name: "Fred",
legs: 4
},
},
hat: {
type: "Baseball Cap",
color: "White",
hex_color: "#eee"
}
}
var test = DiffJSON(n, o);
// --- This is only to prettify the result --- //
var s = JSON.stringify(test).replace(/,/g, ",\n").replace(/{/g, "{\n").replace(/}/g, "\n}");
var ss = s.split("\n");
var count = 0;
var new_s = "";
for (var i=0; i<ss.length; i++) {
var this_ss = ss[i].replace(/^\s+|\s+$/g, "");
if (this_ss.match(/^}/)) { count--; }
new_s += Array(count+1).join(" ") + this_ss + "\n";
if (this_ss.match(/{$/)) { count++; }
}
document.getElementById("output").innerHTML = new_s;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment