Object Diff with Underscore
by drzaus
HTML
<script src="http://underscorejs.org/underscore-min.js"></script>
<div id="debug"></div>
JavaScript
(function(_) {
function deepDiff(a, b, r, reversible) {
_.each(a, function(v, k) {
// already checked this or equal...
if (r.hasOwnProperty(k) || b[k] === v) return;
// but what if it returns an empty object? still attach?
r[k] = _.isObject(v) ? _.diff(v, b[k], reversible) : v;
});
}
/* the function */
_.mixin({
shallowDiff: function(a, b) {
return _.omit(a, function(v, k) {
return b[k] === v;
})
},
diff: function(a, b, reversible) {
var r = {};
deepDiff(a, b, r, reversible);
if(reversible) deepDiff(b, a, r, reversible);
return r;
}
});
/* just so there's something to see */
function dump() {
var args = Array.prototype.slice.call(arguments);
console.log.apply(console, args);
var p = document.createElement('pre');
_.each(args, function(a) {
p.innerText += JSON.stringify(a) + ' ';
});
document.getElementById('debug').appendChild(p);
}
var o1 = {
a: 1,
b: 2,
c: 2
},
o2 = {
a: 2,
b: 1,
c: 2
},
o3 = {
a: 1,
b: 2
};
dump('a = ', o1);
dump('b = ', o2);
dump('c = ', o3);
dump('shallowdiff(a, b) = ', _.shallowDiff(o1, o2));
dump('shallowdiff(b, a) = ', _.shallowDiff(o2, o1));
dump('shallowdiff(a, c) = ', _.shallowDiff(o1, o3));
dump('shallowdiff(c, a) = ', _.shallowDiff(o3, o1));
dump('diff(a, b) = ', _.diff(o1, o2));
dump('diff(b, a) = ', _.diff(o2, o1));
dump('diff(a, c) = ', _.diff(o1, o3));
dump('diff(c, a) = ', _.diff(o3, o1));
dump('diff(c, a, reversible) = ', _.diff(o3, o1, true));
var o3 = {
x: 4,
y: 2,
z: o1,
zz: o1
},
o4 = {
x: 56,
y: 2,
z: o1,
zz: o2
};
dump('o3 = ', o3);
dump('o4 = ', o4);
dump('shallowdiff(o3, o4) = ', _.shallowDiff(o3, o4));
dump('shallowdiff(o4, o3) = ', _.shallowDiff(o4, o3));
dump('diff(o3, o4) = ', _.diff(o3, o4));
...