Javascript 使用DIV中的h1…h6标记数创建树

Javascript 使用DIV中的h1…h6标记数创建树,javascript,html,dom,tree,Javascript,Html,Dom,Tree,几个小时以来,我一直在努力寻找解决方案。我已经做了一些尝试并擦掉了它们,我最近的一次尝试是在这个问题的末尾 假设我希望使用h1…h6标记构建目录,我没有任何使用div等的嵌套。如果目录是父目录或子目录,则标记会通知目录 例如,ah1然后ah2意味着h2是h1的子级 假设我们有一个元素数组: // omitting other properties like 'text', etc for brevity. [{ tag: 2 }, { tag: 2 }, { tag: 3 }, { tag: 3

几个小时以来,我一直在努力寻找解决方案。我已经做了一些尝试并擦掉了它们,我最近的一次尝试是在这个问题的末尾

假设我希望使用
h1
h6
标记构建目录,我没有任何使用div等的嵌套。如果目录是父目录或子目录,则标记会通知目录

例如,a
h1
然后a
h2
意味着
h2
h1
的子级

假设我们有一个元素数组:

// omitting other properties like 'text', etc for brevity.
[{ tag: 2 }, { tag: 2 }, { tag: 3 }, { tag: 3 }, { tag: 4 }, { tag: 2 }]
这将表示以下HTML:

<div>
    <h2>
    <h2>
    <h3>
    <h3>
    <h4>
    <h2>
</div>
这本不应该太难,但我就是想不起来。 我严格地使用数字值来表示它是否是父对象,而不是父对象引用(正如大多数其他问题一样)

  • 如果少了,那就是父母
  • 如果是平等的,那就是兄弟姐妹
  • 如果它更大,那就是一个孩子
下面是我提出的代码,它可以工作,但只能在非常有限的情况下工作。例如,如果在最后一个元素后面有一个同级元素,则它不起作用

谢谢大家!

//Loop through the array backwards
let newArr = [];
let tempArr = [];
while (arr.length) {    
    if (arr.length === 1) {
        newArr.unshift(arr.pop())
    } else {
        let item = arr.pop();

        if (tempArr.length == 0) {
            tempArr.push(item);
            item = arr.pop();
        }

        //Check if the items tag is equal to the tempArrs last item tag
        if (item.tag == tempArr[tempArr.length - 1].tag) {
            tempArr.push(item)
        } else if (item.tag < tempArr[tempArr.length - 1].tag) {



            item.children = tempArr;

            //there might be something in newArr...
            if (newArr.length && newArr[0].tag > item.tag) {
                item.children.push(newArr.pop());
            }

            newArr.unshift(item)
            tempArr = [];
        }
    }
}
//向后循环数组
设newArr=[];
设tempArr=[];
while(arr.length){
如果(arr.length==1){
newArr.unshift(arr.pop())
}否则{
let item=arr.pop();
如果(tempArr.length==0){
临时推(项);
项目=arr.pop();
}
//检查items标记是否等于tempArrs last item标记
if(item.tag==tempArr[tempArr.length-1].tag){
临时推送(项目)
}else if(item.tagitem.tag){
item.children.push(newArr.pop());
}
新到货取消提货(项目)
tempArr=[];
}
}
}

您可以为标高使用辅助数组,并为起始标记获取偏移量(假设没有更小的/父标记可用)

var数组=[{tag:2},{tag:2},{tag:3},{tag:3},{tag:4},{tag:2}],
偏移量=-数组[0]。标记;
结果=[],
级别=[{children:result}];
array.forEach(函数(o){
级别[o.tag+offset]。子级=级别[o.tag+offset]。子级| |[];
级别[o.tag+offset].children.push(级别[o.tag+offset+1]=o);
});
控制台日志(结果)

。作为控制台包装{max height:100%!important;top:0;}
它能否从
标记2
开始并包含
标记1
?或者不同的问题,第一个标签总是最小(最大)的标签吗?是的,第一个标签总是最小的,目前我假设
h1
不会被考虑,因为每篇文章只有一个
h1
标签(通常),然而,用户可能会从h1开始他们的标题,在这种情况下,算法会理想地允许
h1
通过
h6
。换句话说,如果h1被允许,它将允许h2子项,那些h2子项允许h3等等。嗨,我已经标记为接受答案,因为它是有效的。然而,我真的不太明白。我已经在这里对它进行了注释(并做了一些修改):您能告诉我我的注释是否正确吗?那么我想知道你是如何确定偏移量的逻辑的?尤其是它一定是负面的?那么,您如何确定表达式
o.tag+offset+1
?谢谢这个答案很简单,很巧妙,但我不太明白。最简单的方法是,忽略偏移量,并假设标记以零开始。然后假设每个节点都有一个子数组,它与下一级相同,即“+1
leveles`数组包含下一级别的所有alst节点及其子节点<代码>偏移量
标准化
标记
,并将和取为数组的从零开始的索引。
//Loop through the array backwards
let newArr = [];
let tempArr = [];
while (arr.length) {    
    if (arr.length === 1) {
        newArr.unshift(arr.pop())
    } else {
        let item = arr.pop();

        if (tempArr.length == 0) {
            tempArr.push(item);
            item = arr.pop();
        }

        //Check if the items tag is equal to the tempArrs last item tag
        if (item.tag == tempArr[tempArr.length - 1].tag) {
            tempArr.push(item)
        } else if (item.tag < tempArr[tempArr.length - 1].tag) {



            item.children = tempArr;

            //there might be something in newArr...
            if (newArr.length && newArr[0].tag > item.tag) {
                item.children.push(newArr.pop());
            }

            newArr.unshift(item)
            tempArr = [];
        }
    }
}