如何将点分隔字符串动态映射为嵌套 JavaScript 对象

13次阅读

如何将点分隔字符串动态映射为嵌套 JavaScript 对象

本文介绍一种通用、可扩展的方法,将形如 `”a.b.c”` 的键名自动解析为多层嵌套对象结构,并将对应值精准插入最深层,彻底避免硬编码层级判断。

在处理配置化数据(如 iot 设备标签、jsON Schema 路径映射或动态表单字段)时,常需将扁平化的点号分隔键(如 “0_tags.0.Various.Test-String”)还原为树状嵌套对象。原始代码仅支持固定两层(item[0] 和 item[1]),无法应对任意深度的路径,导致可维护性差且易出错。

解决的核心思路是:将路径字符串拆分为键数组,再通过递归或迭代方式逐层“钻取”并创建缺失节点,最终在叶子位置赋值。以下提供两种生产就绪的实现方案:

✅ 方案一:递归实现(清晰易懂)

function createNestedObject(obj, keys, value) {   const [head, ...tail] = keys; // es6 解构,兼容现代环境   if (tail.length === 0) {     obj[head] = value;   } else {     obj[head] = obj[head] || {};     createNestedObject(obj[head], tail, value);   } }  // 使用示例 const tagobject = {   "0_tags.0": { common: {}, native: { topic: "Stromerfassung_251/Zähler0-Leistung" } },   "0_tags.0.Various": { common: {}, native: { topic: "Stromerfassung_251/Zähler0-Leistung" } },   "0_tags.0.Various.Stromerfassung_251/Zähler0-Leistung": { common: {}, native: { topic: "Stromerfassung_251/Zähler0-Leistung" } },   "0_tags.0.Various.Test-String": { common: {}, native: { topic: "Stromerfassung_251/Zähler0-Leistung" } },   "0_tags.0.Various.battery_charge": { common: {}, native: { topic: "Stromerfassung_251/Zähler0-Leistung" } } };  const result = {}; for (const key in tagObject) {   createNestedObject(result, key.split('.'), tagObject[key]); }  console.log(json.stringify(result, null, 2));

✅ 方案二:迭代实现(无溢出风险,推荐用于超深路径)

function setNestedProperty(obj, path, value) {   const keys = path.split('.');   let current = obj;    for (let i = 0; i < keys.length - 1; i++) {     const key = keys[i];     if (current[key] === undefined || typeof current[key] !== 'object') {       current[key] = {};     }     current = current[key];   }    current[keys[keys.length - 1]] = value; }  // 批量应用 const result2 = {}; Object.entries(tagObject).forEach(([key, value]) => {   setNestedProperty(result2, key, value); });

⚠️ 注意事项与最佳实践

  • 键名合法性:若路径含特殊字符(如 . / [),需提前转义或使用 JSONPath 等专用库;
  • 性能考量:对海量键(>10k),迭代版比递归版更稳定(避免 V8 栈限制);
  • 空值防御:示例中使用 obj[head] = obj[head] || {} 替代 undefined 判断,更简洁鲁棒;
  • 不可变更新:如需函数式编程风格,可封装为返回新对象的纯函数(配合 structuredClone 或 Lodash set);
  • 类型安全typescript 用户可定义泛型约束,确保 keys 为 string[],value 类型与目标结构一致。

该方法已广泛应用于 node.js 配置加载器、前端状态归一化(如 Redux Toolkit 的 createEntityAdapter 路径映射)及低代码平台元数据解析场景——一次编写,永久适配任意嵌套深度。

text=ZqhQzanResources