Skip to content

Instantly share code, notes, and snippets.

@sethlivingston
Created July 14, 2021 21:16
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 sethlivingston/4cd896d4e342cc436660df7af487ae00 to your computer and use it in GitHub Desktop.
Save sethlivingston/4cd896d4e342cc436660df7af487ae00 to your computer and use it in GitHub Desktop.
Object diff
// Adapted from https://stackoverflow.com/a/61406094/521662
export interface ObjectComparison {
added?: Record<any, any>;
updated?: Record<string, Change>;
removed?: Record<any, any>;
}
export interface Change {
oldValue: any;
newValue: any;
}
export function diff(
o1: Record<any, any>,
o2: Record<any, any>,
shallow = false
): ObjectComparison {
const added: Record<any, any> = {};
const updated: Record<any, any> = {};
const removed: Record<any, any> = {};
for (const prop in o1) {
if (o1.hasOwnProperty(prop)) {
const o2PropValue = o2[prop];
const o1PropValue = o1[prop];
if (o2.hasOwnProperty(prop)) {
if (o2PropValue !== o1PropValue) {
updated[prop] =
!shallow && isObject(o1PropValue) && isObject(o2PropValue)
? diff(o1PropValue, o2PropValue, shallow)
: { newValue: o2PropValue };
}
} else {
removed[prop] = o1PropValue;
}
}
}
for (const prop in o2) {
if (o2.hasOwnProperty(prop)) {
const o1PropValue = o1[prop];
const o2PropValue = o2[prop];
if (o1.hasOwnProperty(prop)) {
if (o1PropValue !== o2PropValue) {
if (shallow || !isObject(o1PropValue)) {
updated[prop].oldValue = o1PropValue;
}
}
} else {
added[prop] = o2PropValue;
}
}
}
let result: ObjectComparison = {};
if (Object.keys(added).length) result.added = added;
if (Object.keys(updated).length) result.updated = updated;
if (Object.keys(removed).length) result.removed = removed;
return result;
}
function isObject(o: any) {
return o !== null && typeof o === "object";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment