We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Immutability Helper

Number: 2773

Difficulty: Hard

Paid? Yes

Companies: N/A


Problem Description

Given an immutable JSON object (or array), implement a helper class ImmutableHelper that can generate modified versions of that object. The class’s constructor takes an immutable object, and its produce method accepts a mutator function. The mutator function receives a proxied (mutable-appearing) version of the object on which it can make changes; however, these changes must be applied only to a copy such that the original object remains unaffected. The goal is to create a new object that reflects the attempted mutations without modifying the original.


Key Insights

  • The original object must remain unchanged; therefore a deep clone is necessary.
  • A proxy (or similar mechanism) should be provided to the mutator so that mutations are applied to the clone.
  • The mutator function will only perform property updates (no deletions, method calls, or setting properties to objects).
  • A recursive approach is needed for nested objects/arrays, since mutations might occur at any depth.
  • In languages that support Proxy (like JavaScript), use it to trap get and set operations; in others, a deep clone followed by a direct call may suffice given the constraints.

Space and Time Complexity

Time Complexity: O(n) per produce call, where n is the size of the object, for deep cloning. Space Complexity: O(n) to store the deep-copied version of the object.


Solution

The key idea is to isolate the mutations from the original object by:

  1. Creating a deep clone of the original immutable object.
  2. Wrapping the cloned object in a proxy (or a substitute in languages that lack proxy support) that intercepts get/set operations.
  3. Allowing the provided mutator function to operate on the proxy, which in turn alters only the copy.
  4. Returning the modified clone thereby ensuring that the original object is left unchanged.

For JavaScript, the Proxy API is used to intercept property accesses and modifications recursively. In other languages, a deep copy using available library methods is sufficient because the constraints guarantee that no unsupported mutation (like deletion or method calls) will occur.


Code Solutions

# Python Solution
import copy

class ImmutableHelper:
    def __init__(self, obj):
        # Store the original object.
        self.obj = obj

    def produce(self, mutator):
        # Deep clone the original object to ensure immutability.
        new_obj = copy.deepcopy(self.obj)
        # Since Python does not have Proxy like JavaScript,
        # we directly pass the deep clone to the mutator.
        mutator(new_obj)
        # Return the mutated clone.
        return new_obj

# Example usage:
# original_obj = {"x": 5}
# helper = ImmutableHelper(original_obj)
# new_obj = helper.produce(lambda proxy: proxy.update({"x": proxy["x"] + 1}))
# print(original_obj)  # Output: {"x": 5}
# print(new_obj)       # Output: {"x": 6}
← Back to All Questions