如何将含点分隔键的扁平对象转换为嵌套JSON对象?
简洁实现扁平对象转嵌套JSON(支持重复键冲突场景)
以下是更简洁优雅的TypeScript实现,核心逻辑清晰,同时处理了路径冲突(如原有节点为字符串,新增子节点的情况):
function flattenToNested(obj: Record<string, any>): Record<string, any> { const result: Record<string, any> = {}; for (const [path, value] of Object.entries(obj)) { const keys = path.split('.'); let current = result; for (let i = 0; i < keys.length; i++) { const key = keys[i]; const isLast = i === keys.length - 1; // 处理路径冲突:当前节点已是字符串,需转为对象保留原值 if (typeof current[key] === 'string') { current[key] = { [key]: current[key] }; } if (isLast) { current[key] = value; } else { // 确保当前节点是对象,不存在则初始化 current[key] = current[key] || {}; current = current[key]; } } } return result; }
测试示例
基础转换场景
const flatObj = { "test.subtest.pass": "test passed", "test.subtest.fail": "test failed" }; console.log(flattenToNested(flatObj)); // 输出:{ test: { subtest: { pass: 'test passed', fail: 'test failed' } } }
路径冲突场景
当原有路径节点为字符串,新增子路径时,会自动将原有字符串转为对象并保留原值:
const flatObjWithConflict = { "test.subtest.pass": "test passed", "test.subtest.fail": "test failed", "test.subtest.pass.mark": "90" }; console.log(flattenToNested(flatObjWithConflict)); // 输出:{ test: { subtest: { pass: { pass: 'test passed', mark: '90' }, fail: 'test failed' } } }
实现优势
- 逻辑简洁:去掉冗余的中间映射,直接遍历处理每个键值对
- 冲突处理清晰:集中处理字符串节点转对象的场景,避免多层嵌套条件
- 易维护:代码结构直观,后续扩展(如自定义冲突处理规则)更方便
内容的提问来源于stack exchange,提问作者Meggan
相关产品推荐
相关产品推荐

