Skip to content

Instantly share code, notes, and snippets.

@Bengejd
Last active July 26, 2022 19:14
Show Gist options
  • Save Bengejd/19c5bd64d0984ed64ebbde44570e5a47 to your computer and use it in GitHub Desktop.
Save Bengejd/19c5bd64d0984ed64ebbde44570e5a47 to your computer and use it in GitHub Desktop.
Lodash Deep Object Diff Comparison with details
interface DeepComparisonResult {
different: string[];
missing_from_first: string[];
missing_from_second: string[];
differences: { [key: string]: { first: any; second: any } };
}
// Extensive deep diff comparison of two objects.
export const objectDeepComparison = (obj1: any, obj2: any): DeepComparisonResult => {
const compare = (a: any, b: any): DeepComparisonResult => {
const result: DeepComparisonResult = {
different: [],
missing_from_first: [],
missing_from_second: [],
differences: {},
};
const isNotObject = (obj: unknown, key: string) => typeof (obj[key]) !== typeof ({});
// eslint-disable-next-line no-prototype-builtins
const hasProperty = (obj: unknown, key: string) => obj.hasOwnProperty(key);
// eslint-disable-next-line @typescript-eslint/no-shadow
_.reduce(a, (result, value, key) => {
if (!hasProperty(b, key)) {
result.missing_from_second.push(key);
return result;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (_.isEqual(value, b[key])) return result;
if (isNotObject(a, key) || isNotObject(b, key)) {
result.different.push(key);
return result;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const deeper = compare(a[key], b[key]);
result.different = result.different.concat(_.map(deeper.different, (sub_path) => key + "." + sub_path));
result.missing_from_second = result.missing_from_second.concat(_.map(deeper.missing_from_second, (sub_path) => key + "." + sub_path));
result.missing_from_first = result.missing_from_first.concat(_.map(deeper.missing_from_first, (sub_path) => key + "." + sub_path));
return result;
}, result);
// eslint-disable-next-line @typescript-eslint/no-shadow
_.reduce(b, (result, value, key) => {
if (!hasProperty(a, key)) result.missing_from_first.push(key);
return result;
}, result);
return result;
};
const comparisonResults = compare(obj1, obj2);
// A key mapping of what the value is for each object.
comparisonResults.differences = _.reduce(comparisonResults.different, (result, key) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
result[key] = { first: obj1[key], second: obj2[key] };
return result;
}, {});
return comparisonResults;
};
// Lodash Diff comparison from a couple years ago
getDiff() {
const changes = (object, base) => {
let arrayIndexCounter = 0;
return _.transform(object, function (result, value, key) {
if (!_.isEqual(value, base[key])) {
let resultKey = _.isArray(base) ? arrayIndexCounter++ : key;
result[resultKey] = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value;
console.log("Result: " + JSON.stringify(result));
}
});
}
return changes(compareObject, baseObject);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment