如何将含点分隔字符串键的对象转换为嵌套结构对象?
问题解决:将带点路径的对象转换为嵌套对象
需求
原始对象:
const updatedFields = { "user.name": "potato", "plan": "diamond" }
期望转换为嵌套对象:
const obj = { user: { name: "potato" }, plan: "diamond" }
当前代码及错误
当前运行代码:
const updatedFields = { "user.name": "potato", "plan": "diamond" } const obj = {} setpath = ([p,...ps], v, o) => ps.length ? setpath(ps, v, o[p]) : o[p] = v Object.entries(updatedFields).forEach(([p,v]) => setpath(p.split("."), v, obj)) console.log(obj)
出现的错误:
setpath = ([p,...ps], v, o) => ps.length ? setpath(ps, v, o[p]) : o[p] = v ^ TypeError: Cannot set property 'name' of undefined at setpath (/tmp/8LYm4RhWvR.js:8:72) at setpath (/tmp/8LYm4RhWvR.js:8:44) at Object.entries.forEach (/tmp/8LYm4RhWvR.js:9:50) at Array.forEach (<anonymous>) at Object.<anonymous> (/tmp/8LYm4RhWvR.js:9:31) at Module._compile (internal/modules/cjs/loader.js:778:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10) at Module.load (internal/modules/cjs/loader.js:653:32) at tryModuleLoad (internal/modules/cjs/loader.js:593:12) at Function.Module._load (internal/modules/cjs/loader.js:585:3)
错误原因
处理"user.name"时,第一次调用setpath,o[p]即obj['user']是undefined,递归调用时尝试给undefined的name属性赋值,触发类型错误。
解决方案
修改setpath函数,在递归前检查当前路径的对象是否存在,若不存在且还有后续路径,先创建空对象:
const updatedFields = { "user.name": "potato", "plan": "diamond" } const obj = {} const setpath = ([p, ...ps], v, o) => { // 若当前路径节点不存在且还有后续路径,先初始化空对象 if (ps.length && !o[p]) { o[p] = {}; } return ps.length ? setpath(ps, v, o[p]) : (o[p] = v); } Object.entries(updatedFields).forEach(([p, v]) => setpath(p.split("."), v, obj)) console.log(obj)
代码说明
- 新增判断逻辑:当还有后续路径(
ps.length为真)且当前节点o[p]不存在时,将o[p]初始化为空对象,确保递归时有合法的对象可以继续赋值。 - 修正后的函数既能正确处理嵌套路径,也能兼容非嵌套的键(比如
plan)。
内容的提问来源于stack exchange,提问作者jhnxx
相关产品推荐
相关产品推荐

