JavaScript:如何将下划线键扁平对象转为嵌套对象?
扁平对象转嵌套对象实现方案
下面提供两种实用的实现方法,针对输入{a_b_c: 1, a_b_d: 2, a_e: 3, f_g: 4},可输出目标嵌套结构{a: { b: {c: 1, d: 2}, e: 3 }, f: {g: 4}}。
方法一:使用Object.keys() + Array.reduce()
这是简洁的函数式实现方式:
function flattenToNested(obj) { return Object.keys(obj).reduce((result, key) => { const keyPath = key.split('_'); let currentNode = result; // 遍历路径的前n-1个节点,创建嵌套对象 for (let i = 0; i < keyPath.length - 1; i++) { const nodeKey = keyPath[i]; currentNode[nodeKey] = currentNode[nodeKey] || {}; currentNode = currentNode[nodeKey]; } // 给最后一个节点赋值 currentNode[keyPath[keyPath.length - 1]] = obj[key]; return result; }, {}); } // 测试示例 const input = {a_b_c: 1, a_b_d: 2, a_e: 3, f_g: 4}; console.log(flattenToNested(input));
逻辑说明
- 用
Object.keys()提取所有扁平键名,通过reduce初始化空对象作为结果容器。 - 将每个键名按下划线
_拆分成层级路径数组(比如a_b_c拆为['a','b','c'])。 - 遍历路径数组的前n-1个元素,逐层检查并创建嵌套对象,确保路径存在。
- 把对应的值赋给路径的最后一个节点。
方法二:使用for...in循环
如果更倾向于直观的命令式写法,可采用for...in遍历:
function flattenToNested(obj) { const result = {}; for (const flatKey in obj) { if (obj.hasOwnProperty(flatKey)) { const keyPath = flatKey.split('_'); let currentNode = result; for (let i = 0; i < keyPath.length - 1; i++) { const nodeKey = keyPath[i]; // 若当前节点不存在则创建空对象 if (!currentNode[nodeKey]) { currentNode[nodeKey] = {}; } currentNode = currentNode[nodeKey]; } currentNode[keyPath[keyPath.length - 1]] = obj[flatKey]; } } return result; } // 测试示例 const input = {a_b_c: 1, a_b_d: 2, a_e: 3, f_g: 4}; console.log(flattenToNested(input));
逻辑说明
和方法一核心逻辑一致,只是用for...in遍历所有键名,手动维护结果对象和当前层级节点,逻辑更直白。
扩展提示
- 如果键名使用其他分隔符(比如
.或-),只需修改split('_')中的分隔符即可适配。 - 若存在重复的层级路径(比如同时有
a_b和a_b_c),函数会自动合并层级,不会覆盖已有对象;但如果最后一个键名重复,后出现的值会覆盖之前的。
内容的提问来源于stack exchange,提问作者Thắng Nguyễn Quang
相关产品推荐
相关产品推荐

