Skip to content

Instantly share code, notes, and snippets.

@AlexanderWingard
Forked from andrelaszlo/PitTree.scala
Created January 16, 2010 13:28
Show Gist options
  • Save AlexanderWingard/278820 to your computer and use it in GitHub Desktop.
Save AlexanderWingard/278820 to your computer and use it in GitHub Desktop.
import scala.collection.Map
class PitTree[+T](val children : Map[String, PitTree[T]], val value : Option[T]) extends Map[String, T] {
def this() = this(Map(), None)
def this(value : T) = this(Map(), Some(value))
def update[T1 >: T](path : String, upVal : T1) : PitTree[T1] = this.+(path -> upVal)
override def empty = new PitTree[T]
def get(path : String) : Option[T] = get(splitPath(path))
def get(path : List[String]) : Option[T] = path match {
case Nil =>
value
case h :: t =>
if(children.keysIterator.exists(_ == h))
children(h).get(t)
else
None
}
def +[T1 >: T](that: PitTree[T1]) : PitTree[T1] = {
val newChildren = that.children.foldLeft(children.asInstanceOf[Map[String, PitTree[T1]]])((acc, kv) => children.get(kv._1) match {
case Some(exists) => acc + (kv._1 -> (exists + kv._2))
case None => acc + (kv._1 -> kv._2)
})
new PitTree[T1](newChildren, value)
}
def +[T1 >: T](kv: (String, T1)): PitTree[T1] = this.+(splitPath(kv._1), kv._2)
def +[T1 >: T](path : List[String], upVal : T1) : PitTree[T1] = path match {
case Nil =>
new PitTree[T1](upVal)
case h :: t =>
val child = children.getOrElse(h, new PitTree[T1]()).+(t, upVal)
new PitTree[T1](children + (h -> child), value)
}
def - (key: String): PitTree[T] = throw new RuntimeException("Not yet implemented")
def iterator : Iterator[(String, T)] = {
def getIt(prefix : String, tree : PitTree[T], acc: List[(String, T)]) : List[(String, T)] = {
tree.children.foldLeft(acc)((acc2, kv) => {
val path = prefix + "/" + kv._1
val subTree = kv._2
if (kv._2.value.isDefined)
getIt(path, subTree, (path, kv._2.value.get) :: acc2)
else
getIt(path, subTree, acc2)
})
}
getIt("", this, List()).iterator
}
def splitPath(path : String) = path.split('/').filter(_ != "").toList
def filterPath(filter : String) = {
(PitTree[T]() /: filter.split(";")){(tree, expression) =>
tree + this.filter(((kv)) => kv._1.contains(expression)).asInstanceOf[PitTree[T]]
}
}
override def toString = ".\n"+toString(children.toList, "", "")
def toString[T1 >: T](children: List[(String, PitTree[T1])], prefix: String, name: String): String = {
def formatValue(o: Option[T1]): String = o match {
case Some(s) => "= " + s.toString
case None => ""
}
children match {
case Nil => ""
case h::Nil => // last element
val (name, subTree) = h
prefix + "`-- " + name + " " + formatValue(subTree.value) + "\n" +
toString(subTree.children.toList, prefix + " ", name)
case h::t =>
val (name, subTree) = h
prefix + "|-- " + name + " " + formatValue(subTree.value) + "\n" +
toString(subTree.children.toList, prefix + "| ", name) +
toString(t, prefix, name)
}
}
}
object PitTree {
def apply[T]() = new PitTree[T]()
def apply[T](value : T) = new PitTree[T](value)
}
object Test extends Application {
var pitTree = PitTree[Int]()
pitTree = pitTree("/apa") = 10
pitTree = pitTree("/apa") = 20
pitTree = pitTree("gris/kossa/häst") = 30
pitTree = pitTree("gris/kossa/apa") = 10
pitTree = pitTree("gris/kossa/katt/firre") = 4
pitTree = pitTree("flodhaest") = 2
println(pitTree)
//TODO: Add example with comments showing results of operations.
}
.
|-- apa = 20
|-- gris
| `-- kossa
| |-- häst = 30
| |-- apa = 10
| `-- katt
| `-- firre = 4
`-- flodhaest = 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment