跳转至

2691. 不可变辅助工具 🔒

题目描述

创建带有微小修改的不可变对象的克隆副本是一个繁琐的过程。请你编写一个名为 ImmutableHelper 的类,作为满足这一要求的工具。构造函数接受一个不可变对象 obj ,该对象将是一个 JSON 对象或数组。

该类有一个名为 produce 的方法,它接受一个名为 mutator 的函数。该函数返回一个新的对象,它与原始对象相似,但应用了这些变化。

mutator 函数接受 obj代理 版本。函数的使用者可以(看起来)对该对象进行修改,但原始对象 obj 实际上没有被改变。

例如,用户可以编写如下代码:

const originalObj = {"x": 5};
const helper = new ImmutableHelper(originalObj);
const newObj = helper.produce((proxy) => {
  proxy.x = proxy.x + 1;
});
console.log(originalObj); // {"x": 5}
console.log(newObj); // {"x": 6}

mutator 函数的属性:

  • 它始终返回 undefined
  • 它永远不会访问不存在的键。
  • 它永远不会删除键( delete obj.key )。
  • 它永远不会在代理对象上调用方法( pushshift 等)。
  • 它永远不会将键设置为对象( proxy.x = {} )。

关于如何测试解决方案的说明:解决方案验证器仅分析返回结果与原始 obj 之间的差异。进行完全比较的计算开销太大。此外,对原始对象进行的任何变更都将导致答案错误。

 

示例 1:

输入:
obj = {"val": 10}, 
mutators = [
  proxy => { proxy.val += 1; },
  proxy => { proxy.val -= 1; }
]
输出:
[
  {"val": 11},
  {"val": 9}
]
解释:
const helper = new ImmutableHelper({val: 10});
helper.produce(proxy => { proxy.val += 1; }); // { "val": 11 }
helper.produce(proxy => { proxy.val -= 1; }); // { "val": 9 }

示例 2:

输入:
obj = {"arr": [1, 2, 3]} 
mutators = [
 proxy => { 
   proxy.arr[0] = 5; 
   proxy.newVal = proxy.arr[0] + proxy.arr[1];
 }
]
输出:
[
  {"arr": [5, 2, 3], "newVal": 7 } 
]
解释:对原始数组进行了两次编辑。首先将数组的第一个元素设置为 5。然后添加了一个值为 7 的新键。

示例 3:

输入:
obj = {"obj": {"val": {"x": 10, "y": 20}}}
mutators = [
  proxy => { 
    let data = proxy.obj.val; 
    let temp = data.x; 
    data.x = data.y; 
    data.y = temp; 
  }
]
输出:
[
  {"obj": {"val": {"x": 20, "y": 10}}}
]
解释:交换了 "x" 和 "y" 的值。

 

提示:

  • 2 <= JSON.stringify(obj).length <= 4 * 105
  • produce() 的总调用次数 < 105

解法

方法一

1

评论