
Problem Statement
The task is to develop a function capable of evaluating two deeply nested structures, either objects or arrays, referred to here as obj1
and obj2
. This function identifies the differences between these structures and outputs a new object that captures these variations succinctly.
The core functionality revolves around:
- Identifying properties or indices where
obj1
andobj2
differ. - Generating a return object that consists only of entries where differences exist between
obj1
andobj2
. - Representing each difference for keys as an array in the format $value in obj1, value in obj2$.
- Avoiding inclusion of keys that appear only in one of the objects for comparison to ensure that only the differences between shared structures are highlighted.
Arrays are processed similarly to objects with the indication that indices serve as keys for comparison. The function leverages the assumption that both input structures are derived from JSON.parse
, enabling consistency in handling.
Examples
Input:
obj1 = {"a": 1, "b": {"x": 10, "y": 20}, "c": [1, 2, 3]} obj2 = {"a": 1, "b": {"x": 15, "y": 20}, "c": [1, 4, 3]}
Output:
{ "b": { "x": [10, 15] }, "c": { "1": [2, 4] } }
Explanation:
Only the values of `b.x` and `c[1]` differ between the two objects. Other values are identical and thus excluded.
Constraints
obj1
andobj2
are valid objects or arrays parsed fromJSON.parse
1 <= total number of keys or indices <= 10^4
- Nested depth of structures ≤
100
- All primitive values are of types:
string
,number
,boolean
, ornull
- Arrays only contain serializable elements (objects, arrays, or primitives)
- Keys present only in one of the objects are ignored during comparison
Approach and Intuition
By examining the provided examples, we can deduce a general workflow for solving the problem:
Initialize an empty object to store the differences called
diff
.Recursively compare each corresponding key or index in
obj1
andobj2
.For each key:
If both
obj1
andobj2
have the key, and the values differ:- If both values are primitive data types (e.g., string, number), directly compare them.
- If the values differ in type (object/array vs primitive), capture them as is in the difference array.
- If both are objects or arrays, recursively apply the comparison to chart sub-differences.
Omit keys that appear exclusively in one object to focus solely on modifications rather than additions or deletions.
Continue this process recursively for objects within objects or nested arrays.
Ending condition for recursion occurs when all properties have been either matched or the differences have been logged.
Return the
diff
object containing all the captured differences in the prescribed format.
As observed from the examples:
- Changes in either type or value are captured.
- Keys where the value remains unchanged are disregarded to minimize redundancy.
- Array indices are processed similar to object keys, with alterations within arrays marked according to their depth and index, showcasing granularity in difference mapping.
In essence, the goal is to deliver a structured representation that mirrors the inputs' structure but exclusively highlights their discrepancies.
Solutions
- JavaScript
function compareObjects(firstObject, secondObject) {
if (firstObject === secondObject) return {};
if (firstObject === null || secondObject === null) return [firstObject, secondObject];
if (typeof firstObject !== 'object' || typeof secondObject !== 'object') return [firstObject, secondObject];
if (Array.isArray(firstObject) !== Array.isArray(secondObject)) return [firstObject, secondObject];
const differences = {};
for (const property in firstObject) {
if (property in secondObject) {
const diff = compareObjects(firstObject[property], secondObject[property]);
if (Object.keys(diff).length > 0) {
differences[property] = diff;
}
}
}
return differences;
}
This JavaScript function, compareObjects
, checks for differences between two input objects and returns an object representing the differences. It follows these steps to achieve this:
Checks if the two objects are exactly the same instance. If true, returns an empty object
{}
since there are no differences.Checks if either object is
null
. If either isnull
, returns an array containing both objects since comparing anull
with any object will generally lead to a difference.Validates if both variables are indeed objects (not primitives). If either is not an object, returns an array with both variables.
Checks if the type mismatches between objects; specifically, whether one is an array and the other is not. Returns both objects in an array if they differ in type (array vs non-array).
Initializes an empty object
differences
to collect properties that differ. Iterates over properties of the first object and for each property:- Compares properties in both objects recursively by calling
compareObjects
again. - If recursive comparison finds differences (i.e., the returned object has keys), adds these differences to the
differences
object under the respective property name.
- Compares properties in both objects recursively by calling
Returns the
differences
object containing all properties that show variation between the two objects.
This function provides a deep comparison that can navigate through nested structures within objects, making it useful for identifying not just surface-level differences but also those buried within nested objects or arrays.
No comments yet.