JavaScript字符串转对象:自定义映射转换问题求助
解决自定义$标签字符串转嵌套对象的问题
先帮你梳理清楚从输入输出推导出来的转换规则:
$X表示开启一个新节点,节点值为X,这个节点会成为当前活跃节点的子节点,同时当前活跃节点切换为这个新节点X$表示关闭当前节点,当前活跃节点切换回它的父节点- 像
$TT$这类连续字符串其实是$T(开启)+T$(关闭)的组合,最终生成一个没有子节点的叶子节点
非递归方案(用栈实现,直观易调试)
栈天生适合处理这种嵌套层级结构,我们可以用栈来跟踪当前的父节点链:
function transformToNestedObj(str) { // 栈:保存当前的父节点链,初始创建一个虚拟根节点来承载最终的根节点 const stack = [{ chld: [] }]; let i = 0; // 每次处理两个字符(标签是$+字母或字母+$的固定格式) while (i < str.length) { const currentSlice = str.slice(i, i + 2); if (currentSlice.startsWith('$')) { // 处理开启节点:$X const nodeValue = currentSlice[1]; const newNode = { v: nodeValue }; // 把新节点添加到当前栈顶节点的子节点列表中 if (!stack[stack.length - 1].chld) { stack[stack.length - 1].chld = []; } stack[stack.length - 1].chld.push(newNode); // 将新节点压入栈,作为下一个节点的父节点 stack.push(newNode); i += 2; } else if (currentSlice.endsWith('$')) { // 处理关闭节点:X$,弹出栈顶回到父节点 stack.pop(); i += 2; } else { // 容错处理:如果遇到不符合格式的片段,跳过一个字符继续 i += 1; } } // 返回虚拟根节点的第一个子节点,也就是真正的根节点 return stack[0].chld[0]; } // 测试你的输入 const input = '$B$O$TT$O$$KK$$Z$HH$$U$PP$$QQ$U$Z$B$'; const result = transformToNestedObj(input); console.log(JSON.stringify(result, null, 2));
运行代码后,输出完全符合你的预期:
{ "v": "B", "chld": [ { "v": "O", "chld": [ { "v": "T" } ] }, { "v": "K" }, { "v": "Z", "chld": [ { "v": "H" }, { "v": "U", "chld": [ { "v": "P" }, { "v": "Q" } ] } ] } ] }
聊聊你原递归函数的问题
你的递归代码没正常工作主要有这几个原因:
- 只处理了
$X开启节点的逻辑,完全没实现X$关闭节点的回溯逻辑,导致无法回到父节点添加新的子节点 - 没有维护父节点的引用,每次创建新节点后无法正确关联到父节点的
chld数组 - 递归的终止条件和返回值逻辑不完整,遇到关闭节点或字符串处理完时没有正确返回结果
如果一定要用递归实现,本质也是模拟栈的逻辑,但非递归的栈方案更直观,也更容易调试。
补充优化点
- 如果需要即使没有子节点也保留
chld: [],可以在创建新节点时默认初始化这个属性 - 可以添加输入合法性校验,比如检查标签是否配对、是否有非法字符等
内容的提问来源于stack exchange,提问作者me_man
相关产品推荐
相关产品推荐

