在 Lodash 中有条件合并两个对象

问题描述 投票:0回答:1

我有两个设置配置

const defaultSetting = {
  level1: {
    setting1: "defaultValue1",
    nested: true,
    home: "africa"
  },
  level2: {
    setting2: "defaultValue3"
  }
};

const initialSetting = {
  level1: {
    setting1: "initialValue1", // This value will override defaultSetting's value
    nested: false // This value will override defaultSetting's value
  },
  level2: {
    nested: true // This value will override defaultSetting's value, adding a new property not in defaultSetting's level2
  }
};

我想要实现的是我想将initialSetting合并到defaultSetting中,这样:

  1. defaultSetting 的结构决定了最终的结构。
  2. initialSetting 中的值会覆盖 defaultSetting 中的值 存在。
  3. 如果initialSetting包含不存在于 defaultSetting,它们不包含在最终对象中。
  4. 如果defaultSetting包含initialSetting中不存在的键,则它们 保留默认值。

我想严格遵守defaultSetting的结构,同时有选择地从initialSetting中提取值。

我有这个代码

const mergeTwoObjects = (obj11: NestedObject | undefined, obj2: NestedObject): unknown => {
 const result: NestedObject = {};
  const obj1 = obj11 ?? {};

  (Object.keys(obj2) as Array<keyof typeof obj2>).forEach((key) => {
    if (Object.prototype.hasOwnProperty.call(obj1, key)) {
      if (typeof obj1[key] === "object" && typeof obj2[key] === "object") {
        result[key] = mergeTwoObjects(
          obj1[key] as NestedObject,
          obj2[key] as NestedObject,
        ) as NestedObject;
      } else {
        result[key] = obj1[key];
      }
    } else {
      result[key] = obj2[key];
    }
  });
  return result;
};

但要求是我不能从头开始构建我的函数,而不是我应该使用 lodash 并使代码简单而不需要很多循环

我试过了,但没用

const defaultSetting = {
  level1: {
    setting1: "defaultValue1",
    nested: true,
    home: "africa"
  },
  level2: {
    setting2: "defaultValue3"
  }
};

const initialSetting = {
  level1: {
    setting1: "initialValue1", // This value will override defaultSetting's value
    nested: false // This value will override defaultSetting's value
  },
  level2: {
    nested: true // This value will override defaultSetting's value, adding a new property not in defaultSetting's level2
  }
};

function mergeSettings(defaultSetting, initialSetting) {
  return _.mergeWith({}, defaultSetting, initialSetting, (objValue, srcValue, key, object, source, stack) => {
      if (_.isObject(objValue) && _.isObject(srcValue)) {
          // Return undefined to let _.mergeWith handle the deep merge of these objects
          return undefined;
        }
    // If srcValue is undefined, use objValue (from defaultSetting)
    return srcValue === undefined ? objValue : srcValue;
  });
}

const finalSetting = mergeSettings(defaultSetting, initialSetting);

console.log(finalSetting);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

我是 Lodash 的新手,有人可以帮我实现这个目标吗

我想要得到的是:

{
  "level1": {
    "setting1": "initialValue1",
    "nested": false,
    "home": "africa"
  },
  "level2": {
    "setting2": "defaultValue3",
  }
}
javascript lodash
1个回答
-1
投票

这在 lodash 方法的确切意义上是不可能的。最接近的是,您可以取消来自初始对象中不存在的对象的所有值。否则请使用

mergeWith
omit
的组合。缺失值为 null 的示例:

const defaultSetting = {
  level1: {
    setting1: "defaultValue1",
    nested: true,
    home: "africa"
  },
  level2: {
    setting2: "defaultValue3"
  }
};

const initialSetting = {
  level1: {
    setting1: "initialValue1", // This value will override defaultSetting's value
    nested: false // This value will override defaultSetting's value
  },
  level2: {
    nested: true // This value will override defaultSetting's value, adding a new property not in defaultSetting's level2
  }
};

function customiser(objValue, srcValue) {
  if (_.isNil(objValue))
    return null;
}

const finalSetting = _.mergeWith(defaultSetting, initialSetting, customiser);
console.log(finalSetting);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.