Deep (but slow) comparison of JSON-serializable JS objects
// I'm using this now in my Alloy runtime testing to assert that the | |
// proper styles are getting assigned to Titanium proxy objects. The | |
// deep comparison is necessary for objects like font in the style. So | |
// for my purposes the accuracy of the results far supercedes the lack | |
// of blazing performance with this code. I'm using underscore.js as | |
// it's part of Alloy, but isX() calls could easily be filled out in | |
// a couple lines of JS. | |
// | |
// Obviously due to the use of JSON.stringify() the objects to be | |
// compared need to be JSON serializable. | |
function sortAndStringify(obj) { | |
// make use of the JSON.stringify() "replacer" parameter, which allows | |
// us to transform any given key or value as it is encountered. We'll | |
// use it to sort any objects (but not arrays or funcs) that we encounter. | |
// | |
// https://developer.mozilla.org/en-US/docs/Using_native_JSON#The_replacer_parameter | |
return JSON.stringify(obj, function(k,v) { | |
if (_.isObject(v) && !_.isArray(v) && !_.isFunction(v)) { | |
return sortObject(v); | |
} | |
return v; | |
}); | |
} | |
// re-inserts object keys in alphabetical order. This code is not mine, I've | |
// seen it a couple places. Not sure to whom I should give credit. | |
function sortObject(o) { | |
var sorted = {}, | |
key, a = []; | |
for (key in o) { | |
if (o.hasOwnProperty(key)) { | |
a.push(key); | |
} | |
} | |
a.sort(); | |
for (key = 0; key < a.length; key++) { | |
sorted[a[key]] = o[a[key]]; | |
} | |
return sorted; | |
} | |
// Now I can compare 2 deeply nested JS objects | |
if (sortAndStringify(object1) === sortAndStringify(object2)) { | |
// hey, I did a deep comparison! | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment