Given a list of weighted headings, produce a nested ordered list in html.
“H1 All About Birds”,
“H2 Kinds of Birds”,
“H3 The Finch”,
“H3 The Swan”,
“H2 Habitats”,
“H3 Wetlands”
The above list should produce the following:
- Kinds of Birds
- The Finch
- The Swan
- Habitats
- Wetlands
You are given the following code to start with, and only the function toOutline(headings) should be implemented.
const headingData = [ "H1 All About Birds", "H2 Kinds of Birds", "H3 The Finch", "H3 The Swan", "H2 Habitats", "H3 Wetlands", "H2 Kinds of Birds", "H3 The Finch", "H3 The Swan", "H2 Habitats", "H3 Wetlands", "H4 Zoo", "H4 Trees" ] const Heading = function(weight, text) { this.weight = weight; this.text = text }; const Node = function(heading, children) { this.heading = heading; this.children = children; }; function toOutline(headings) { // Implement this function. Sample code below builds // an outline of only the first heading // let root = new Node(new Heading(0, ""), [new Node(headings[0], [])]) // return root } // Parses a line of the input // This implementation is correct for all predefined test cases function parse(record) { const firstSpace = record.indexOf(" "); const weight = parseInt(record.substr(1, firstSpace)); const text = record.substr(firstSpace + 1); return new Heading(weight, text); } // Converts a node to HTML function toHtml(node) { let childHtml = ""; if (node.children.length > 0) { childHtml =<ol>${node.children.map(child =>
<li>${toHtml(child)}</li>).join("\n")}</ol>
; } const heading = node.heading.text.length === 0 ? "" : node.heading.text + "\n"; return heading + childHtml; } const headings = headingData.map(r => parse(r)); const outline = toOutline(headings); console.log(toHtml(outline[0]));
One solution is to recursively build Nodes, comparing the current heading’s weight to the previous heading’s weight.
function toOutline(headings) { let cur = headings[0] let nodes = buildNodes(cur, headings) return nodes } function buildNodes(prev, headings) { let nodes = [] let cur = null while (headings.length > 0) { let cur = headings[0] if (cur.weight == prev.weight) { headings.shift() nodes.push(new Node(cur, [])) } else if (cur.weight > prev.weight) { let childNodes = buildNodes(cur, headings) let n = nodes.pop() // remove previous and concat to it nodes.push(new Node(n.heading, childNodes)) } else { // cur.weight < prev.weight return nodes } } return nodes }
The solution produces the following results:
All About Birds- Kinds of Birds
- The Finch
- The Swan
- Habitats
- Wetlands
- Kinds of Birds
- The Finch
- The Swan
- Habitats
- Wetlands
- Zoo
- Trees
- Wetlands