{"id":1009,"date":"2019-07-15T18:29:58","date_gmt":"2019-07-15T22:29:58","guid":{"rendered":"https:\/\/resrvoir.com\/?page_id=1009"},"modified":"2019-07-15T18:46:47","modified_gmt":"2019-07-15T22:46:47","slug":"nested-headings","status":"publish","type":"page","link":"https:\/\/resrvoir.com\/?page_id=1009","title":{"rendered":"Nested Headings"},"content":{"rendered":"\n<p>Given a list of weighted headings, produce a nested ordered list in html. <br><br>&#8220;H1 All About Birds&#8221;,<br>&#8220;H2 Kinds of Birds&#8221;,<br>&#8220;H3 The Finch&#8221;,<br>&#8220;H3 The Swan&#8221;,<br>&#8220;H2 Habitats&#8221;,<br>&#8220;H3 Wetlands&#8221;<br><br>The above list should produce the following:<\/p>\n\n\n\nAll About Birds\n<ol>\n  <li>Kinds of Birds\n<ol><li>\n    The Finch\n  <\/li>\n  <li>\n    The Swan\n  <\/li>\n<\/ol>\n<\/li>\n  <li>Habitats\n  <ol><li>\n   Wetlands\n <\/li><\/ol>\n<\/li><\/ol>\n\n\n\n\n<p>You are given the following code to start with, and only the function <strong>toOutline(headings) <\/strong>should be implemented.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const headingData = [\n  \"H1 All About Birds\",\n  \"H2 Kinds of Birds\",\n  \"H3 The Finch\",\n  \"H3 The Swan\",\n  \"H2 Habitats\",\n  \"H3 Wetlands\",\n  \"H2 Kinds of Birds\",\n  \"H3 The Finch\",\n  \"H3 The Swan\",\n  \"H2 Habitats\",\n  \"H3 Wetlands\",\n  \"H4 Zoo\",\n  \"H4 Trees\"\n]\n\nconst Heading = function(weight, text) {\n  this.weight = weight;\n  this.text = text\n};\nconst Node = function(heading, children) {\n  this.heading = heading;\n  this.children = children;\n};\n\nfunction toOutline(headings) {\n    \/\/ Implement this function. Sample code below builds\n    \/\/ an outline of only the first heading\n\n    \/\/ let root = new Node(new Heading(0, \"\"), [new Node(headings[0], [])])\n    \/\/ return root\n}\n\n\/\/ Parses a line of the input\n\/\/ This implementation is correct for all predefined test cases\nfunction parse(record) {\n  const firstSpace = record.indexOf(\" \");\n  const weight = parseInt(record.substr(1, firstSpace));\n  const text = record.substr(firstSpace + 1);\n  return new Heading(weight, text);\n}\n\n\/\/ Converts a node to HTML\nfunction toHtml(node) {\n  let childHtml = \"\";\n  if (node.children.length > 0) {\n    childHtml = <code data-enlighter-language=\"raw\" class=\"EnlighterJSRAW\">&lt;ol&gt;${node.children.map(child =&gt; <\/code>&lt;li>${toHtml(child)}&lt;\/li><code data-enlighter-language=\"raw\" class=\"EnlighterJSRAW\">).join(&quot;\\n&quot;)}&lt;\/ol&gt;<\/code>;\n  }\n  const heading = node.heading.text.length === 0 ? \"\" : node.heading.text + \"\\n\";\n  return heading + childHtml;\n}\n\nconst headings = headingData.map(r => parse(r));\nconst outline = toOutline(headings);\nconsole.log(toHtml(outline[0]));\n<\/pre>\n\n\n\n<p>One solution is to recursively build Nodes, comparing the current heading&#8217;s weight to the previous heading&#8217;s weight. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">function toOutline(headings) {\n    let cur = headings[0]\n    let nodes = buildNodes(cur, headings)\n    return nodes\n}\n\nfunction buildNodes(prev, headings) {\n  let nodes = []\n  let cur = null\n\n  while (headings.length > 0) {\n    let cur = headings[0]\n\n    if (cur.weight == prev.weight) {\n      headings.shift()\n      nodes.push(new Node(cur, []))\n    }\n    else if (cur.weight > prev.weight) {\n      let childNodes = buildNodes(cur, headings)\n\n      let n = nodes.pop() \/\/ remove previous and concat to it\n      nodes.push(new Node(n.heading, childNodes))\n    }\n    else { \/\/ cur.weight &lt; prev.weight\n      return nodes\n    }\n  }\n\n  return nodes\n}\n<\/pre>\n\n\n\n<p>The solution produces the following results:<\/p>\n\n\n\nAll About Birds\n<ol><li>Kinds of Birds\n<ol><li>The Finch\n<\/li>\n<li>The Swan\n<\/li><\/ol><\/li>\n<li>Habitats\n<ol><li>Wetlands\n<\/li><\/ol><\/li>\n<li>Kinds of Birds\n<ol><li>The Finch\n<\/li>\n<li>The Swan\n<\/li><\/ol><\/li>\n<li>Habitats\n<ol><li>Wetlands\n<ol><li>Zoo\n<\/li>\n<li>Trees\n<\/li><\/ol><\/li><\/ol><\/li><\/ol>\n\n","protected":false},"excerpt":{"rendered":"<p>Given a list of weighted headings, produce a nested ordered list in html. &#8220;H1 All About Birds&#8221;,&#8220;H2 Kinds of Birds&#8221;,&#8220;H3 The Finch&#8221;,&#8220;H3 The Swan&#8221;,&#8220;H2 Habitats&#8221;,&#8220;H3 Wetlands&#8221; The above list should produce the following: All About Birds Kinds of Birds The Finch The Swan Habitats Wetlands You are given the following code to start with, and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":2,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"_links":{"self":[{"href":"https:\/\/resrvoir.com\/index.php?rest_route=\/wp\/v2\/pages\/1009"}],"collection":[{"href":"https:\/\/resrvoir.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/resrvoir.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/resrvoir.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/resrvoir.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1009"}],"version-history":[{"count":19,"href":"https:\/\/resrvoir.com\/index.php?rest_route=\/wp\/v2\/pages\/1009\/revisions"}],"predecessor-version":[{"id":1031,"href":"https:\/\/resrvoir.com\/index.php?rest_route=\/wp\/v2\/pages\/1009\/revisions\/1031"}],"up":[{"embeddable":true,"href":"https:\/\/resrvoir.com\/index.php?rest_route=\/wp\/v2\/pages\/2"}],"wp:attachment":[{"href":"https:\/\/resrvoir.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}