如何将HTML标题(h2-h6)数组转换为树形结构?
Got it, let's break down how to turn your flat list of HTML headers (with their rank values mapping to h2-h6) into the nested tree structure you need. This is a typical problem when building document outlines, and the solution relies on tracking the current hierarchy as we iterate through each header.
Core Idea
We'll use a stack to keep track of the current path in the tree. Each entry in the stack holds a node and its rank, so we can easily find the correct parent for each new header by comparing ranks.
Step-by-Step Breakdown
- Initialize an empty tree array (for root nodes) and an empty stack.
- Loop through each header:
- Create a new node with the header text and an empty
childrenarray. - Pop from the stack until we find a parent whose rank is exactly one less than the current header's rank (this ensures we're attaching to the correct level).
- If the stack is empty, this header is a root node—add it directly to the tree.
- Otherwise, add the new node to the parent's
childrenarray. - Push the new node and its rank onto the stack so it can be a parent for subsequent child headers.
- Create a new node with the header text and an empty
Working JavaScript Implementation
Here's a tested function that does exactly this:
function headersToTree(headers) { const tree = []; const stack = []; headers.forEach(({ text, rank }) => { const newNode = { text, children: [] }; // Find the appropriate parent by removing higher/equal rank nodes from stack while (stack.length && stack.at(-1).rank >= rank) { stack.pop(); } if (!stack.length) { tree.push(newNode); } else { stack.at(-1).node.children.push(newNode); } // Add current node to stack for future children stack.push({ rank, node: newNode }); }); return tree; } // Test with your sample input const sampleHeaders = [ { text: 'Some header', rank: 2 }, { text: 'Some another header', rank: 3 }, { text: 'A header with the same rank', rank: 3 }, { text: 'One more subsection header', rank: 4 } ]; const resultTree = headersToTree(sampleHeaders); console.log(JSON.stringify(resultTree, null, 2));
Sample Output
Running this code will produce the structure you requested (with the rank 4 header nested under the second rank 3 header, which makes sense for document hierarchy):
[ { "text": "Some header", "children": [ { "text": "Some another header", "children": [] }, { "text": "A header with the same rank", "children": [ { "text": "One more subsection header", "children": [] } ] } ] } ]
Why This Works
- The stack acts as a "breadcrumb trail" of the current hierarchy. When we encounter a header with a lower rank than the top of the stack, we backtrack until we find the right parent.
- This approach handles all valid hierarchy shifts—whether moving down to a deeper level (e.g., h2 → h3 → h4) or back up (e.g., h4 → h3 → h2).
- It's efficient, running in O(n) time since each header is pushed and popped from the stack at most once.
内容的提问来源于stack exchange,提问作者Laraleg

