Javascript 如何修复此算法以在AST中创建嵌套节

Javascript 如何修复此算法以在AST中创建嵌套节,javascript,algorithm,recursion,abstract-syntax-tree,Javascript,Algorithm,Recursion,Abstract Syntax Tree,我正在努力创建一个算法,它接受一个兄弟元素数组(DOM节点的抽象表示)并返回通过嵌套增强的数组。嵌套规则非常简单:每个标题都开始一个新的部分,该部分一直延伸到同一级别的下一个标题(或列表的末尾)。每个节中都可以有更多嵌套节,使用相同的规则 背景:我正在尝试将我的CMS中的AST转换为一种结构,该结构在关于交互式粘性目录的文章中给出。目前,我只使用标题来创建类似的效果(例如),但效果并不是很流畅 我能够创建一些嵌套,但我的大脑不太喜欢这样的递归算法,我至少遇到了一个bug——嵌套的一部分填充了不必

我正在努力创建一个算法,它接受一个兄弟元素数组(DOM节点的抽象表示)并返回通过嵌套增强的数组。嵌套规则非常简单:每个标题都开始一个新的部分,该部分一直延伸到同一级别的下一个标题(或列表的末尾)。每个节中都可以有更多嵌套节,使用相同的规则

背景:我正在尝试将我的CMS中的AST转换为一种结构,该结构在关于交互式粘性目录的文章中给出。目前,我只使用标题来创建类似的效果(例如),但效果并不是很流畅

我能够创建一些嵌套,但我的大脑不太喜欢这样的递归算法,我至少遇到了一个bug——嵌套的一部分填充了不必要的数组(注意第一个“heading3”等等)

到目前为止,我得到的是:

let list=[“heading1”、“1”、“1”、“heading2”、“1-1”、“1-1”、“heading3”、“1-1-1”、“heading3”、“1-1-2”、“1-1-2”、“heading2”、“1-2”、“1-2”、“heading1”、“heading2”、“2-2”、“heading1”、“3”、“heading1”、“4”、“4”]
让findFirstHeading=(list,level)=>list.findIndex(el=>newregexp(`heading${level}').test(el))
让splitIntoSections=(列表,级别)=>{
让startIndex=findFirstHeading(列表,级别)
//注意:虽然这看起来过于复杂,但这是为了防止bug,当findIndex返回-1时,添加startIndex+1将给出错误的值。
让endIndex=
findFirstHeading(list.slice(startIndex+1),级别)=-1?
-1 :
findFirstHeading(list.slice(startIndex+1),level)+startIndex+1
让PrecingList=list.slice(0,startIndex)
让restOfList=endIndex>-1?list.slice(endIndex):null
返回restOfList?[…前序列表,
拆分为多个部分(list.slice(startIndex,endIndex),级别+1),
…拆分为多个部分(restOfList,级别)
]:[名单]
}

console.log(JSON.stringify(splitIntoSections(list,1),null,2))
通常在编写递归算法时,我避免源数组的副本或子副本,而是选择索引来跟踪源数组中的当前位置,主要是为了避免数组复制对性能的影响。通常我发现,让主函数需要最小的参数,并在主函数中嵌入实际的递归函数以及递归函数所需的任何变量的初始化,这是一个更干净的函数接口

我在下面的代码中嵌入了一些注释,以帮助理解递归逻辑

函数嵌套(数组){
函数递归(currentLevel){
让结果=[];
while(索引console.log(嵌套(列表))虽然我肯定会接受@Trentium提供的答案,但同时我自己也发现了代码中的错误:

有一个案例我没有想到:在列表的一部分中没有找到标题。在这种情况下,我应该返回
list
,而不是
[list]
(因此需要额外的嵌套级别)

let list=[“heading1”、“1”、“1”、“heading2”、“1-1”、“1-1”、“heading3”、“1-1-1”、“heading3”、“1-1-2”、“1-1-2”、“heading2”、“1-2”、“1-2”、“heading1”、“heading2”、“2-2”、“heading1”、“3”、“heading1”、“4”、“4”]
让findFirstHeading=(list,level)=>list.findIndex(el=>newregexp(`heading${level}').test(el))
让splitIntoSections=(列表,级别)=>{
让startIndex=findFirstHeading(列表,级别)
if(startIndex==-1){/-1?list.slice(endIndex):null
返回restOfList?[…前序列表,
拆分为多个部分(list.slice(startIndex,endIndex),级别+1),
…拆分为多个部分(restOfList,级别)
]:[名单]
}
}

log(JSON.stringify(splitIntoSections(list,1),null,2))
噢,谢谢!我真的很感激你所做的工作。关于更干净的界面和更少的内存需求,您肯定是对的。我会接受你的回答。(在此期间,我成功地在代码中找到了bug,因此我也将添加自己的答案。)