【问题标题】:Deep merge objects without cloning无需克隆即可深度合并对象
【发布时间】:2021-01-15 04:52:23
【问题描述】:

我想合并两个对象而不克隆或改变其中之一。

function merge(defaultOptions, userOptions) {
    // userOptions should not be cloned or mutated but should get priority over defaultOptions
    return res;
}

我正在使用 lodash,但 _merge 并没有多大帮助。由于 userOptions 可能很大,我想避免克隆它。

请注意,改变或克隆 defaultOptions 是可以的,因为它不会影响我系统的性能。

执行此操作的最佳方法是什么?

【问题讨论】:

  • 你想要一个新的对象还是改变一个?
  • 为什么 lodashes 合并没有多大帮助?它完全符合您的要求。它会变异defaultOptions,这对你来说没问题。
  • @NinaScholz 我愿意改变 defaultOptions 或创建一个新选项。正如我所提到的,我不介意克隆 defaultOptions 所以无论如何都没关系。
  • @JohannesKlauß _.merge(defaultOptions, userOptions) 会克隆 userOptions,这是非常昂贵的。同时,_.merge(userOptions, defaultOptions) 会覆盖我不想要的 userOptions。
  • @gt18 你在哪里找到这些信息的?快速查看源代码并不表明源对象正在被克隆。

标签: javascript object merge lodash


【解决方案1】:

您可以使用Object destructuring 这个解决方案将通过合并两个对象的属性来创建一个新对象。

const newObject = {
  ...obj1,
  ...obj2
}

假设res是一个对象,你可以试试下面的

return { ...res }

【讨论】:

  • 这不会进行深度合并。我需要进行深度合并。
  • ps,这是object rest/spread syntax(不是解构)
  • 这将克隆解构的对象,但只克隆第一级。传播不会深度克隆。
  • @LeandroMatilla 我已经浏览了链接,但我看到了接受的答案,因为这是不可能的。另外,我认为 lodash 的合并是解决该问题的一种可能方法,但它对我没有帮助。
【解决方案2】:

您可以迭代userOptions 的条目并改变defaultOptions

function merge(defaultOptions, userOptions) {
    Object.entries(userOptions).forEach(([key, value]) => {
        if (value && typeof value === 'object') merge(defaultOptions[key] = defaultOptions[key] || [], value);
        else defaultOptions[key] = value;
    });
    return defaultOptions;
}

【讨论】:

    【解决方案3】:

    所以,我自己实现了它,它似乎工作得很好。

    /**
     * Custom merge function with in place merge with behaviour similar to that of _.merge.
     *
     * @param {object} tar target object in which the other object is to be merged
     * @param {object} src source object which is to be merged
     * @returns object merged object
     */
    function inPlaceMerge(tar, src) {
        let res = tar;
        if (_.isObject(src) && _.isObject(tar)) {
            _.forEach(src, (val, key) => {
                    res[key] = inPlaceMerge(tar[key], val);
            })        
        } else if (src !== undefined) {
            res = src;
        }
        return res;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-09-09
      • 2012-06-05
      • 2013-09-06
      • 2013-10-11
      • 2018-03-21
      • 2019-03-25
      • 1970-01-01
      相关资源
      最近更新 更多