Last active
February 13, 2019 04:26
-
-
Save apruden/3b98f84f08c5de47113305242749e603 to your computer and use it in GitHub Desktop.
fictional document management system - outline
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Heading(weight: Int, text: String) | |
case class Node(heading: Heading, children: List[Node]) | |
/** Converts a list of input headings into nested nodes */ | |
def toOutline(headings: List[Heading]): Node = { | |
def buildNodes(input: List[Heading]): List[Node] = input match { | |
case Nil => Nil | |
case head :: Nil => Node(head, Nil) :: Nil | |
case head +: tail => | |
tail.splitAt(tail.indexWhere(head.weight == _.weight)) match { | |
case (Nil, rest) => | |
if (rest.head.weight == head.weight) | |
Node(head, Nil) +: buildNodes(rest) | |
else | |
Node(head, buildNodes(rest)) :: Nil | |
case (children, rest) => Node(head, buildNodes(children)) +: buildNodes(rest) | |
} | |
} | |
Node(Heading(0, ""), buildNodes(headings)) | |
} | |
def toOutline2(headings: List[Heading]): Node = { | |
def addToNode(target:Node, node:Node): Node = { | |
require(node.heading.weight > target.heading.weight) | |
if (target.children.isEmpty || target.children.last.heading.weight == node.heading.weight) | |
target.copy(children=target.children :+ node) | |
else | |
target.copy(children = target.children.init :+ addToNode(target.children.last, node)) | |
} | |
val nodes = headings.map(Node(_, List.empty)) | |
nodes.tail.foldLeft(nodes.head)(addToNode) | |
} | |
def parse(record: String): Option[Heading] = { | |
val H = "H(\\d+)".r | |
record.split(" ", 2) match { | |
case Array(H(level), text) => | |
scala.util.Try(Heading(level.toInt, text.trim)).toOption | |
case _ => None | |
} | |
} | |
val input = """H1 All About Birds | |
H2 Kinds of Birds | |
H3 The Finch | |
H3 The Swan | |
H2 Habitats | |
H3 Wetlands""" | |
toOutline(input.split("\n").flatMap(parse).toList) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment