Skip to content

Instantly share code, notes, and snippets.

@ayxos
Created November 26, 2019 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayxos/245ad2f397ebbc42b170ca856cec11a7 to your computer and use it in GitHub Desktop.
Save ayxos/245ad2f397ebbc42b170ca856cec11a7 to your computer and use it in GitHub Desktop.
Object Diff JS
/* !
* Find the differences between two objects and push to a new object
* @param {Object} obj1 The original object
* @param {Object} obj2 The object to compare against it
* @return {Object} An object of differences between the two
*/
export const getDiff = (obj1, obj2) => {
// Make sure an object to compare is provided
if (!obj2 || Object.prototype.toString.call(obj2) !== '[object Object]') {
return obj1;
}
const diffs = {};
let key;
/**
* Check if two arrays are equal
* @param {Array} arr1 The first array
* @param {Array} arr2 The second array
* @return {Boolean} If true, both arrays are equal
*/
const arraysMatch = (arr1, arr2) => {
// Check if the arrays are the same length
if (arr1.length !== arr2.length) return false;
// Check if all items exist and are in the same order
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) return false;
}
// Otherwise, return true
return true;
};
/**
* Compare two items and push non-matches to object
* @param {*} item1 The first item
* @param {*} item2 The second item
* @param {String} key The key in our object
*/
const compare = (item1, item2, selectedKey) => {
// Get the object type
const type1 = Object.prototype.toString.call(item1);
const type2 = Object.prototype.toString.call(item2);
// If type2 is undefined it has been removed
if (type2 === '[object Undefined]') {
diffs[selectedKey] = null;
return;
}
// If items are different types
if (type1 !== type2) {
diffs[selectedKey] = item2;
return;
}
// If an object, compare recursively
if (type1 === '[object Object]') {
const objDiff = getDiff(item1, item2);
if (Object.keys(objDiff).length) {
diffs[selectedKey] = objDiff;
}
return;
}
// If an array, compare
if (type1 === '[object Array]') {
if (!arraysMatch(item1, item2)) {
diffs[selectedKey] = item2;
}
return;
}
// Else if it's a function, convert to a string and compare
// Otherwise, just compare
if (type1 === '[object Function]') {
if (item1.toString() !== item2.toString()) {
diffs[selectedKey] = item2;
}
}
else if (item1 !== item2) {
diffs[selectedKey] = item2;
}
};
// Loop through the first object
for (key in obj1) {
if (obj1.hasOwnProperty(key)) {
compare(obj1[key], obj2[key], key);
}
}
// Loop through the second object and find missing items
for (key in obj2) {
if (obj2.hasOwnProperty(key)) {
if (!obj1[key] && obj1[key] !== obj2[key]) {
diffs[key] = obj2[key];
}
}
}
// Return the object of differences
return diffs;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment