Skip to content

Instantly share code, notes, and snippets.

@johntbush
Last active November 22, 2016 22:24
Show Gist options
  • Save johntbush/7eabe19ae9d6991b4b20706eb48757a8 to your computer and use it in GitHub Desktop.
Save johntbush/7eabe19ae9d6991b4b20706eb48757a8 to your computer and use it in GitHub Desktop.
sample tree
package com.trax.platform.parse
import scala.annotation.tailrec
import org.json4s._
import org.json4s.native.Serialization
import org.json4s.native.Serialization.{read, write}
import org.json4s.FieldSerializer._
import JsonDSL._
import org.junit.Test
class TreeTest {
/**
* Created by johnbush on 11/21/16.
*/
case class Node(name:String, data:Map[String, String] = Map.empty[String, String], var children:List[Node] = List.empty[Node]) {
def addChild(node:Node) = {
children = children :+ node
children
}
}
object TreeManager {
val tree = Node("idoc", Map.empty, List.empty)
def root:Node = tree
def createNode(name:String, data:Map[String, String] = Map.empty[String, String]) = {
Node(name, data, List.empty[Node])
}
def findNode(nodeName:String):Option[Node] = findNode(nodeName, tree)
def findNode(nodeName:String, currentNode:Node):Option[Node] = {
if (currentNode.name == nodeName)
Option(currentNode)
else {
val foundNode = currentNode.children.find(_.name == nodeName)
if (foundNode.isDefined) foundNode
else {
currentNode.children.foldLeft(None) { (n, child) =>
val foundNode = findNode(nodeName, child)
if (foundNode.isDefined) return foundNode
None
}
}
}
}
def addNode(parent:String, node:Node):Unit =
findNode(parent).foreach(_.addChild(node))
def printTree:Unit = printTree(root, 0)
def printTree(currentNode:Node, level:Int):Unit = {
(0 to level).map(x => print("\t"))
println(currentNode.name + " => " + currentNode.toString)
currentNode.children.map( node => printTree(node, level + 1))
}
class NodeSerializer extends Serializer[Node] {
private val MyClassClass = classOf[Node]
def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), Node] = {
case (TypeInfo(MyClassClass, _), json) => json match {
case JObject(JField("name", JString(name)) :: _) =>
Node(name)
case x => throw new MappingException("Can't convert " + x + " to MyClass")
}
}
def jsonify(currentNode:Node): JObject = {
val children = currentNode.children.map( node => jsonify(node))
if (children.isEmpty)
(currentNode.name -> (currentNode.data.map { case (k,v) => k -> v}))
else
(currentNode.name -> ("children" -> children) ~ (currentNode.data.map { case (k,v) => k -> v}))
}
def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
case x: Node => jsonify(root)
}
}
def toJson:String = {
implicit val formats = Serialization.formats(NoTypeHints) + new NodeSerializer
write(tree)
}
}
@Test
def test1(): Unit = {
TreeManager.root.addChild(TreeManager.createNode("1", Map("seg1"-> "a", "seg2" -> "b")))
TreeManager.root.addChild(TreeManager.createNode("2"))
TreeManager.addNode("1", TreeManager.createNode("1-1"))
TreeManager.addNode("2", TreeManager.createNode("2-1"))
TreeManager.addNode("3", TreeManager.createNode("3-1"))
TreeManager.addNode("1-1", TreeManager.createNode("1-1-1", Map("seg1"-> "a", "seg2" -> "b")))
TreeManager.addNode("1-1", TreeManager.createNode("1-1-1", Map("seg1"-> "ab", "seg2" -> "bc")))
TreeManager.addNode("1-1", TreeManager.createNode("1-1-2", Map("seg1"-> "x", "seg2" -> "y")))
TreeManager.addNode("1-1-1", TreeManager.createNode("1-1-1-1", Map("seg1"-> "x", "seg2" -> "y")))
TreeManager.addNode("1-1-1", TreeManager.createNode("1-1-1-2", Map("seg1"-> "x", "seg2" -> "y")))
TreeManager.addNode("1-1", TreeManager.createNode("1-1-2"))
println(TreeManager.printTree)
println(TreeManager.findNode("1-1").toString)
println(TreeManager.findNode("2").toString)
println(TreeManager.findNode("1").toString)
println(TreeManager.toJson)
}
}
@johntbush
Copy link
Author

output looks like this:

	root => Node(root,Map(),List(Node(1,Map(seg1 -> a, seg2 -> b),List(Node(1-1,Map(),List(Node(1-1-1,Map(seg1 -> a, seg2 -> b),List()), Node(1-1-1,Map(seg1 -> x, seg2 -> y),List()), Node(1-1-2,Map(),List()))))), Node(2,Map(),List(Node(2-1,Map(),List())))))
		1 => Node(1,Map(seg1 -> a, seg2 -> b),List(Node(1-1,Map(),List(Node(1-1-1,Map(seg1 -> a, seg2 -> b),List()), Node(1-1-1,Map(seg1 -> x, seg2 -> y),List()), Node(1-1-2,Map(),List())))))
			1-1 => Node(1-1,Map(),List(Node(1-1-1,Map(seg1 -> a, seg2 -> b),List()), Node(1-1-1,Map(seg1 -> x, seg2 -> y),List()), Node(1-1-2,Map(),List())))
				1-1-1 => Node(1-1-1,Map(seg1 -> a, seg2 -> b),List())
				1-1-1 => Node(1-1-1,Map(seg1 -> x, seg2 -> y),List())
				1-1-2 => Node(1-1-2,Map(),List())
		2 => Node(2,Map(),List(Node(2-1,Map(),List())))
			2-1 => Node(2-1,Map(),List())
()
Some(Node(1-1,Map(),List(Node(1-1-1,Map(seg1 -> a, seg2 -> b),List()), Node(1-1-1,Map(seg1 -> x, seg2 -> y),List()), Node(1-1-2,Map(),List()))))
Some(Node(2,Map(),List(Node(2-1,Map(),List()))))
Some(Node(1,Map(seg1 -> a, seg2 -> b),List(Node(1-1,Map(),List(Node(1-1-1,Map(seg1 -> a, seg2 -> b),List()), Node(1-1-1,Map(seg1 -> x, seg2 -> y),List()), Node(1-1-2,Map(),List()))))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment