Compact Object

Updated on 21 May, 2025
Compact Object header image

Problem Statement

The task is to define a function that accepts an input in the form of an object or array, obj, and returns a new version of this object, termed a compact object. A compact object retains the structure and keys of the original object but omits any keys or indices associated with falsy values. Key points to note about falsy values are that these are values which, when evaluated in a Boolean context, yield false. These typically include false, 0, "" (empty string), null, undefined, and NaN.

This operation not only affects the top-level elements of obj but also its nested structures. Hence if obj is a deeply nested object, all levels will be subjected to this compacting process. Arrays are treated as objects too, where array indices act as object keys.

Since the input is assumed to result from JSON.parse, it will always be in the form of a valid JSON, which confines our values to numbers, strings, booleans, arrays, objects, null, but not functions or date objects.

Examples

Example 1

Input:

obj = [null, 0, false, 1]

Output:

[1]

Explanation:

All falsy values have been removed from the array.

Example 2

Input:

obj = {"a": null, "b": [false, 1]}

Output:

{"b": [1]}

Explanation:

obj["a"] and obj["b"][0] had falsy values and were removed.

Example 3

Input:

obj = [null, 0, 5, [0], [false, 16]]

Output:

[5, [], [16]]

Explanation:

obj[0], obj[1], obj[3][0], and obj[4][0] were falsy and removed.

Constraints

  • obj is a valid JSON object
  • 2 <= JSON.stringify(obj).length <= 106

Approach and Intuition

The steps to solve this problem can be broken into several clear phases:

  1. Identify if the current item (either from object or array) is falsy. If yes, skip adding this to the result.

  2. Check whether the item is an array or object:

    • If the element is an array or object, recursively process each element of the array or key-value pair in the object with the same conditional check for falsiness.
  3. If the element is not falsy and not an object or array (i.e., it's a primary data type like string, number, boolean), directly add it to the resulting structure unless it's falsy.

For nested structures, the method recursively ensures that the check and removal of falsy values is applied thoroughly down to the deepest nested object or array. Finally, the cleaned structure, free from all falsy associated keys or indices, is returned.

Additional Insights:

  • Handling of Empty Arrays and Objects: Post removal of falsy values, objects or arrays that become empty should be considered in the structural integrity of the output. For example, an object that had all falsy values should itself not appear if nested within another object or array.

  • Performance Considerations: Given that the upper limit for the JSON string representation of the object can be quite large (up to 1,000,000 characters), the function's efficiency, particularly in terms of recursion depth and handling large nested structures efficiently, becomes paramount.

Overall, the process involves constructing a new version of the input by systematically removing undesired content while preserving the nested structure and essential content fidelity of the original obj.

Solutions

  • JavaScript
js
function simplifyStructure(data) {
    const dataStack = [[data, Array.isArray(data) ? [] : {}]];
    let simplifiedData = dataStack[0][1];

    while (dataStack.length > 0) {
        const [current, newCurrent] = dataStack.pop();

        for (const key in current) {
            const value = current[key];
            if (!value) continue;
            
            if (typeof value !== 'object') {
                Array.isArray(newCurrent) ? newCurrent.push(value) : newCurrent[key] = value;
                continue;
            }

            const newArrayOrObject = Array.isArray(value) ? [] : {};
            Array.isArray(newCurrent) ? newCurrent.push(newArrayOrObject) : newCurrent[key] = newArrayOrObject;
            dataStack.push([value, newArrayOrObject]);
        }
    }

    return simplifiedData;
}

The function simplifyStructure in JavaScript is crafted to reduce the complexity of an input data structure, which could be either an object or an array, by recursively iterating through it. This trimmed version excludes any falsy values (like null, undefined, false, etc.) and reconstructs the structure with only the truthy values remaining. The result maintains the original structure type of array or object. Below is an explanation of the code workflow and mechanics:

  1. Initialize dataStack with the original data and an empty structure of the same type (array or object).
  2. Define simplifiedData to reference the first element of dataStack, which serves as the accumulator for the result.
  3. Use a while loop to process each element in the stack until it's empty:
    • Extract the current element and its corresponding new structure (newCurrent) from the top of the stack.
    • Iterate through each key-value pair in the current element:
      • Skip processing if the value is falsy.
      • Directly assign non-object values to the corresponding position in newCurrent.
      • If the value is an object or array, create a new empty structure of the same type, assign it to the corresponding position in newCurrent, and push it onto the stack for future processing.
  4. Continue until all objects/arrays have been fully traversed and simplified.
  5. Return the simplifiedData which now holds the processed data maintaining the initial structure with only truthy values.

This approach ensures data integrity while stripping away unwanted falsy values, making the data cleaner and potentially reducing memory usage if the data structure is large.

Comments

No comments yet.