From 21c3208ea2f42c327f3c487fb6c66b32ff34dac0 Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Thu, 24 Apr 2025 06:14:54 +0000 Subject: [PATCH] Add utility for comparing objects by specified properties --- .../utils/compareObjectsByProperties/index.js | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 packages/app/src/utils/compareObjectsByProperties/index.js diff --git a/packages/app/src/utils/compareObjectsByProperties/index.js b/packages/app/src/utils/compareObjectsByProperties/index.js new file mode 100644 index 00000000..e8e95b63 --- /dev/null +++ b/packages/app/src/utils/compareObjectsByProperties/index.js @@ -0,0 +1,99 @@ +export default function compareObjectsByProperties(obj1, obj2, props) { + // validate that obj1 and obj2 are objects + if ( + !obj1 || + !obj2 || + typeof obj1 !== "object" || + typeof obj2 !== "object" + ) { + return false + } + + // validate that props is an array + if (!Array.isArray(props)) { + throw new Error("The props parameter must be an array") + } + + // iterate through each property and compare + for (const prop of props) { + // check if the property exists in both objects + const prop1Exists = prop in obj1 + const prop2Exists = prop in obj2 + + // if the property doesnt exist in one of the objects + if (prop1Exists !== prop2Exists) { + return false + } + + // if the property exists in both, compare values + if (prop1Exists && prop2Exists) { + // for nested objects, perform deep comparison + if ( + typeof obj1[prop] === "object" && + obj1[prop] !== null && + typeof obj2[prop] === "object" && + obj2[prop] !== null + ) { + // compare arrays + if (Array.isArray(obj1[prop]) && Array.isArray(obj2[prop])) { + if (obj1[prop].length !== obj2[prop].length) { + return false + } + + for (let i = 0; i < obj1[prop].length; i++) { + // if elements are objects, call recursively + if ( + typeof obj1[prop][i] === "object" && + typeof obj2[prop][i] === "object" + ) { + // get all properties of the object + const nestedProps = [ + ...new Set([ + ...Object.keys(obj1[prop][i]), + ...Object.keys(obj2[prop][i]), + ]), + ] + + if ( + !compareObjectsByProperties( + obj1[prop][i], + obj2[prop][i], + nestedProps, + ) + ) { + return false + } + } else if (obj1[prop][i] !== obj2[prop][i]) { + return false + } + } + } + // compare objects + else { + const nestedProps = [ + ...new Set([ + ...Object.keys(obj1[prop]), + ...Object.keys(obj2[prop]), + ]), + ] + + if ( + !compareObjectsByProperties( + obj1[prop], + obj2[prop], + nestedProps, + ) + ) { + return false + } + } + } + // for primitive values, compare directly + else if (obj1[prop] !== obj2[prop]) { + return false + } + } + } + + return true +}