Last active
October 23, 2024 08:34
-
-
Save digitaldrreamer/477a7d0766492d276f899b140bebce3b to your computer and use it in GitHub Desktop.
A Function to Compare Two Objects and Get The Difference or return `null`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Compares two objects and returns the differences, or null if they're the same | |
* @param {Object} original - Original form data | |
* @param {Object} current - Current form data | |
* @returns {Object|null} Object containing only the changed fields, or null if no changes | |
*/ | |
function getObjectDiff(original, current) { | |
const changes = {}; | |
for (const [key, value] of Object.entries(current)) { | |
// Handle case where original doesn't have the key | |
if (!(key in original)) { | |
changes[key] = { | |
oldValue: undefined, | |
newValue: value | |
}; | |
continue; | |
} | |
const originalValue = original[key]; | |
const currentValue = value; | |
if ( | |
originalValue !== currentValue && | |
String(originalValue) !== String(currentValue) && | |
JSON.stringify(originalValue) !== JSON.stringify(currentValue) | |
) { | |
changes[key] = { | |
old: originalValue, | |
new: currentValue | |
}; | |
} | |
} | |
// Check for keys that exist in original but not in current | |
for (const key of Object.keys(original)) { | |
if (!(key in current)) { | |
changes[key] = { | |
old: original[key], | |
new: undefined | |
}; | |
} | |
} | |
// Return null if no changes were found | |
return Object.keys(changes).length === 0 ? null : changes; | |
} | |
function deepObjectDiff(original, current) { | |
if (original === current) return null; | |
// Handle non-object types (including null) | |
if ( | |
typeof original !== 'object' || | |
typeof current !== 'object' || | |
original === null || | |
current === null | |
) { | |
return { | |
oldValue: original, | |
newValue: current | |
}; | |
} | |
// Handle arrays | |
if (Array.isArray(original) && Array.isArray(current)) { | |
if (original.length !== current.length) { | |
return { | |
oldValue: original, | |
newValue: current | |
}; | |
} | |
const arrayDiffs = {}; | |
let hasChanges = false; | |
for (let i = 0; i < original.length; i++) { | |
const diff = deepObjectDiff(original[i], current[i]); | |
if (diff !== null) { | |
arrayDiffs[i] = diff; | |
hasChanges = true; | |
} | |
} | |
return hasChanges ? arrayDiffs : null; | |
} | |
const changes = {}; | |
let hasChanges = false; | |
// Check for changes in current object | |
for (const key of Object.keys(current)) { | |
if (!(key in original)) { | |
changes[key] = { | |
oldValue: undefined, | |
newValue: current[key] | |
}; | |
hasChanges = true; | |
continue; | |
} | |
const diff = deepObjectDiff(original[key], current[key]); | |
if (diff !== null) { | |
changes[key] = diff; | |
hasChanges = true; | |
} | |
} | |
// Check for deleted keys | |
for (const key of Object.keys(original)) { | |
if (!(key in current)) { | |
changes[key] = { | |
oldValue: original[key], | |
newValue: undefined | |
}; | |
hasChanges = true; | |
} | |
} | |
return hasChanges ? changes : null; | |
} | |
export {getObjectDiff, deepObjectDiff}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { getObjectDiff, deepObjectDiff } from './objectDiff.js'; | |
// Test Cases | |
console.log("Test 1: Identical objects"); | |
console.log(getObjectDiff( | |
{ name: "John", age: 30 }, | |
{ name: "John", age: 30 } | |
)); | |
// Output: null | |
console.log("Test 2: Different objects"); | |
console.log(getObjectDiff( | |
{ name: "John", age: 30 }, | |
{ name: "Jane", age: 30 } | |
)); | |
// Output: { name: { oldValue: "John", newValue: "Jane" } } | |
console.log("Test 3: Nested objects"); | |
const original = { | |
name: "John", | |
age: 30, | |
address: { | |
street: "123 Main St", | |
city: "Boston" | |
}, | |
hobbies: ["reading", { type: "sports", name: "basketball" }] | |
}; | |
const current = { | |
name: "John", | |
age: 30, | |
address: { | |
street: "123 Main St", | |
city: "New York" // Changed city | |
}, | |
hobbies: ["reading", { type: "sports", name: "football" }] // Changed sport | |
}; | |
console.log("Shallow comparison result:", getObjectDiff(original, current)); | |
// const shallowOutput = { | |
// address: { | |
// oldValue: { | |
// street: "123 Main St", | |
// city: "Boston" | |
// }, | |
// newValue: { | |
// street: "123 Main St", | |
// city: "New York" | |
// } | |
// }, | |
// hobbies: { | |
// oldValue: ["reading", { type: "sports", name: "basketball" }], | |
// newValue: ["reading", { type: "sports", name: "football" }] | |
// } | |
// } | |
console.log("Deep comparison result:", deepObjectDiff(original, current)); | |
// const deepOutput = { | |
// address: { | |
// city: { | |
// oldValue: "Boston", | |
// newValue: "New York" | |
// } | |
// }, | |
// hobbies: { | |
// "1": { | |
// name: { | |
// oldValue: "basketball", | |
// newValue: "football" | |
// } | |
// } | |
// } | |
// } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment