本文介绍如何将形如 `"0_tags.0.various.test-string"` 的键名自动解析并构建为深层嵌套对象结构,避免硬编码层级,支持任意深度的路径映射。
在处理配置驱动型数据(如 IoT 设备标签、JSON Schema 路径或表单字段映射)时,常需将扁平化的点号分隔键(例如 "root.child.grandchild")动态还原为对应的嵌套对象结构。若采用 if 判断逐层创建(如 obj[a][b][c] = value),不仅代码冗余、难以维护,更无法应对不确定的嵌套深度。
核心思路是将每个键按 . 分割为路径数组,再通过递归或迭代方式逐级下钻创建中间对象,最终在叶子节点赋值:
function createNestedObject(obj, keys, value) {
const [head, ...tail] = keys;
if (tail.length === 0) {
// 到达末级:直接赋值
obj[head] = value;
} else {
// 中间层级:确保子对象存在,继续递归
if (!obj[head] || typeof obj[head] !== 'object') {
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));? 输出效果:自动合并同前缀路径,生成符合预期的嵌套结构——如 "0_tags.0.Various.X" 全部归入 result["0_tags"]["0"]["Various"] 下,且各子项保留原始 common/native 数据。
function setByPath(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] || typeof current[key] !== 'object') {
current[key] = {};
}
current = current[key];
}
current[keys.at(-1)] = v
alue;
}掌握该模式后,你不仅能精准还原题设中的多层设备标签结构,还可无缝扩展至动态表单生成、路由配置树、JSON Patch 路径解析等场景——真正实现“一法通百用”。