Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function findDifferences(objectA, objectB) {
- var propertyChanges = [];
- var objectGraphPath = ["this"];
- (function(a, b) {
- if(a.constructor == Array) {
- // BIG assumptions here: That both arrays are same length, that
- // the members of those arrays are _essentially_ the same, and
- // that those array members are in the same order...
- for(var i = 0; i < a.length; i++) {
- objectGraphPath.push("[" + i.toString() + "]");
- arguments.callee(a[i], b[i]);
- objectGraphPath.pop();
- }
- } else if(a.constructor == Object || (a.constructor != Number &&
- a.constructor != String && a.constructor != Date &&
- a.constructor != RegExp && a.constructor != Function &&
- a.constructor != Boolean)) {
- // we can safely assume that the objects have the
- // same property lists, else why compare them?
- for(var property in a) {
- objectGraphPath.push(("." + property));
- if(a[property].constructor != Function) {
- arguments.callee(a[property], b[property]);
- }
- objectGraphPath.pop();
- }
- } else if(a.constructor != Function) { // filter out functions
- if(a != b) {
- propertyChanges.push({ "Property": objectGraphPath.join(""), "ObjectA": a, "ObjectB": b });
- }
- }
- })(objectA, objectB);
- return propertyChanges;
- }
- var person1 = {
- FirstName : "John",
- LastName : "Doh",
- Age : 30,
- EMailAddresses : [
- "john.doe@gmail.com",
- "jd@initials.com"
- ],
- Children : [
- {
- FirstName : "Sara",
- LastName : "Doe",
- Age : 2
- }, {
- FirstName : "Beth",
- LastName : "Doe",
- Age : 5
- }
- ]
- };
- var person2 = {
- FirstName : "John",
- LastName : "Doe",
- Age : 33,
- EMailAddresses : [
- "john.doe@gmail.com",
- "jdoe@hotmail.com"
- ],
- Children : [
- {
- FirstName : "Sara",
- LastName : "Doe",
- Age : 3
- }, {
- FirstName : "Bethany",
- LastName : "Doe",
- Age : 5
- }
- ]
- };
- var differences = findDifferences(person1, person2);
- [
- {
- "Property":"this.LastName",
- "ObjectA":"Doh",
- "ObjectB":"Doe"
- }, {
- "Property":"this.Age",
- "ObjectA":30,
- "ObjectB":33
- }, {
- "Property":"this.EMailAddresses[1]",
- "ObjectA":"jd@initials.com",
- "ObjectB":"jdoe@hotmail.com"
- }, {
- "Property":"this.Children[0].Age",
- "ObjectA":2,
- "ObjectB":3
- }, {
- "Property":"this.Children[1].FirstName",
- "ObjectA":"Beth",
- "ObjectB":"Bethany"
- }
- ]
- // Given two objects find the first key or value not matching, algorithm is a
- // inspired by of _.isEqual.
- function diffObjects(a, b) {
- console.info("---> diffObjects", {"a": a, "b": b});
- // Check object identity.
- if (a === b) return true;
- // Different types?
- var atype = typeof(a), btype = typeof(b);
- if (atype != btype) {
- console.info("Type mismatch:", {"a": a, "b": b});
- return false;
- };
- // Basic equality test (watch out for coercions).
- if (a == b) return true;
- // One is falsy and the other truthy.
- if ((!a && b) || (a && !b)) {
- console.info("One is falsy and the other truthy:", {"a": a, "b": b});
- return false;
- }
- // Unwrap any wrapped objects.
- if (a._chain) a = a._wrapped;
- if (b._chain) b = b._wrapped;
- // One of them implements an isEqual()?
- if (a.isEqual) return a.isEqual(b);
- // Check dates' integer values.
- if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
- // Both are NaN?
- if (_.isNaN(a) && _.isNaN(b)) {
- console.info("Both are NaN?:", {"a": a, "b": b});
- return false;
- }
- // Compare regular expressions.
- if (_.isRegExp(a) && _.isRegExp(b))
- return a.source === b.source &&
- a.global === b.global &&
- a.ignoreCase === b.ignoreCase &&
- a.multiline === b.multiline;
- // If a is not an object by this point, we can't handle it.
- if (atype !== 'object') {
- console.info("a is not an object:", {"a": a});
- return false;
- }
- // Check for different array lengths before comparing contents.
- if (a.length && (a.length !== b.length)) {
- console.info("Arrays are of different length:", {"a": a, "b": b});
- return false;
- }
- // Nothing else worked, deep compare the contents.
- var aKeys = _.keys(a), bKeys = _.keys(b);
- // Different object sizes?
- if (aKeys.length != bKeys.length) {
- console.info("Different object sizes:", {"a": a, "b": b});
- return false;
- }
- // Recursive comparison of contents.
- for (var key in a) if (!(key in b) || !diffObjects(a[key], b[key])) return false;
- return true;
- };
Add Comment
Please, Sign In to add comment