【问题标题】:Deep merging two Immutable maps while ignoring nested arrays在忽略嵌套数组的同时深度合并两个不可变映射
【发布时间】:2021-05-28 22:43:46
【问题描述】:

const map1 = Immutable.Map({ a: { x: 1, z: 1, y: 1, values: [1, 2, 3] } });
const map2 = Immutable.Map({ a: { x: 2, values: [4, 5, 6] } });

const map3 = map1.mergeDeep(map2)

// Output I want is:
// { a: { x: 2, z: 1, y: 1 values: [4, 5, 6] } }

假设我有两张地图。其中一张地图是另一张地图的部分对象,不一定包含所有相同的属性。我想合并它们,包括嵌套对象,但不合并数组。如上所示,它更新了两个地图中存在的属性,保留了新第二个地图中不存在的旧属性,并且只使用了最新的地图数组而不是将它们合并到 [1,2,3 ,4,5,6]。我该怎么做?

【问题讨论】:

    标签: javascript immutable.js


    【解决方案1】:

    这个问题似乎与this stackoverflow 帖子有关。正如那里所说,使用fromJS 而不是Map 可以得到所需的结果。此外,this 回答很好地解释了两者之间的区别。请参考并运行下面的 sn-p 以获取工作示例:

    const map1 = Immutable.fromJS({ a: { x: 1, z: 1, y: 1, values: [1, 2, 3] } });
    const map2 = Immutable.fromJS({ a: { x: 2, values: [4, 5, 6] } });
    
    const map3 = map1.mergeDeep(map2)
    
    console.log(map3)
    
    // Output I want is:
    // { a: { x: 2, z: 1, y: 1 values: [4, 5, 6] } }
    
    /* And this snippet results in:
    {
      "a": {
        "x": 2,
        "z": 1,
        "y": 1,
        "values": [
          4,
          5,
          6
        ]
      }
    }
    */
    <script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js" integrity="sha512-9XVMKQr4ymAxO4jZVbEM2eq01aGlTY4bMlWyQh+KcQWprFkWu5KpOcDOa3RLFZc586QHihZPd1b8XzXqweRxIQ==" crossorigin="anonymous"></script>

    【讨论】:

    • 如果你运行它,你会看到值的长度为 6,我希望将数组替换为 [4,5,6],而不是合并
    • @GregM 我很困惑,如果你运行 sn-p,这正是你得到的,值数组被 [4,5,6] 替换。你在使用其他版本的 immutable 吗?
    【解决方案2】:

    您没有说明您使用的 immutable.js 版本,但是您问的方式,它可能是 4.0.0-rc12。 Immutable.js 3.8.x 版本的 mergeDeep 函数做了你想要的;它替换了数组而不是合并它们。这就是为什么@etarhan 的答案有效但对您无效。

    没有“好的”解决方案。 mergeDeepWith 函数让您定义一个合并函数,但遗憾的是合并仅在冲突时触发 - 所以它也对您没有帮助。您所能做的就是手动遍历对象或升级 immutable.js。

    还请注意,Immutable.Map({ a: { x: 1, z: 1, y: 1, values: [1, 2, 3] } }); 只会对输入进行浅层转换。 values 的数组仍然是一个数组。这通常是不希望的,您可能希望拥有一个 Immutable.List 而不是数组。为此,请使用 fromJS,它会转换 depply。

    我会在 slack 频道上提出这个问题,IMO 应该也有可能在集合上调用合并。

    类似的事情可能会完成这项工作:

    const map1 = Immutable.fromJS({ a: { x: 'one', z: 'old', y: 'old', values: [1, 2, 3] } });
    const map2 = Immutable.fromJS({ a: { x: 'two', v: 'new', values: [4, 5, 6] } });
    
    
    function mergeStuff(a, b, path = '') {
      return a.withMutations(map => {
        for(key of b.keys()) {
          map.update(key, (val) => {
            console.log('updating', path + key, val, b.get(key));
            if(Immutable.isKeyed(val)) {
              return mergeStuff(val, b.get(key), key + '.');
            }
            return b.get(key, val);
          });
        }
      });
    }
    
    const map3 = mergeStuff(map1, map2);
    
    console.log('result:');
    console.log(map3);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.12/immutable.js"></script>

    【讨论】:

      猜你喜欢
      • 2018-08-23
      • 2017-09-25
      • 1970-01-01
      • 2014-03-02
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      相关资源
      最近更新 更多