Problem Description
Given a JSON object or array and a filtering function fn that returns a boolean, perform a deep filter operation. Remove any properties or elements for which fn returns false, and also remove any objects or arrays that become empty after filtering. If the entire object or array becomes empty, return undefined.
Key Insights
- Use recursion to traverse nested objects and arrays.
- When encountering an object or array, recursively filter each property or element.
- Apply fn to primitive values (or non-object/array values) to decide if they should be kept.
- After filtering substructures, if an object or array is empty, treat it as invalid and remove it from the final result.
- The solution must handle edge cases such as deeply nested empty objects/arrays.
Space and Time Complexity
Time Complexity: O(n), where n is the total number of elements/properties in the input. Space Complexity: O(d), where d is the maximum depth of the nested structures due to recursion.
Solution
We solve the problem using a recursive depth-first search. For each node in the object or array:
- If the node is an object or an array, iterate over its keys or indices, recursively call the deep filter on the value, and include the value only if the recursive call returns a defined (non-empty) value.
- For other values (non-objects/arrays), apply the filter function fn. If fn returns true, keep the value; otherwise, drop it.
- After processing an object or an array, if no valid entries remain, return undefined to indicate the structure is empty.
- This approach ensures that by the time we have filtered higher levels, all invalid entries (including empty nested structures) have been removed.