Public
Edited
Nov 14, 2023
Insert cell
Insert cell
input = [
{
level: "2",
content: "How is a manuscript and its figures read?",
id: "how-is-a-manuscript-and-its-figures-read%3F"
},
{
level: "3",
content: "Sub heading",
id: "sub-heading"
},
{
level: "3",
content: "Sub heading",
id: "sub-heading"
},
{
level: "4",
content: "A sub-sub heading",
id: "sub-sub-heading"
},
{
level: "2",
content: "Another heading",
id: "another-heading"
}
]
Insert cell
/**
* Adds a hierarchy to the headings.
* 1. Initialization of root: We start by creating a placeholder root object with a children property. This is like an imaginary parent for all top-level headings.
* 2. Initialization of stack: A stack (an array in this context) is initialized with the root object. We will use this stack to maintain and track the hierarchy of headings as we go through the array.
* 3. Iterate through the headings: Using a for...of loop, we go through each heading in the provided array.
* 4. Initialize children property: For each heading, we initialize its children property as an empty array. This will hold nested headings if they exist.
* 5. Pop from the stack: The while loop here checks if the current heading's level is less than or equal to the level of the last heading in the stack. If so, it pops headings off the stack. This is done to find the correct parent for the current heading.
* 6. Add current heading to parent: Once the correct parent is found (i.e., the last heading in the stack after the while loop), we push the current heading into its children array.
* 7. Push current heading to stack: After associating the current heading with its parent, we then push the heading itself onto the stack. This allows it to potentially be a parent for subsequent headings.
* 8. Return the result: Finally, after processing all headings, we return the children of the root object, which will hold the desired hierarchical structure.
* @param {Array} headings - The headings.
* @returns {Array} The headings with a hierarchy.
*/
Insert cell
function addHierarchy(headings) {
const root = { children: [] }; // 1. Placeholder to maintain the hierarchy.
const stack = [root]; // 2. Starts with the root placeholder.

headings.forEach((heading) => {
// 3.
heading.children = []; // 4. Add a children property to each heading.

while (stack.length && stack[stack.length - 1].level >= heading.level) {
stack.pop(); // 5. Remove elements from the stack until we find the correct parent.
}

// 6. Add the current heading as a child of the last item in the stack.
stack[stack.length - 1].children.push(heading);

// 7. Add the current heading to the stack.
stack.push(heading);
});

return root.children; // 8. The desired hierarchical structure.
}
Insert cell
addHierarchy(input)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more