Skip to content

Instantly share code, notes, and snippets.

@gstraymond
Last active February 15, 2018 20:15
Show Gist options
  • Save gstraymond/213650fbc7cc0eecd7afbd53bf2cacc8 to your computer and use it in GitHub Desktop.
Save gstraymond/213650fbc7cc0eecd7afbd53bf2cacc8 to your computer and use it in GitHub Desktop.
Scala Trie
case class Trie(char: Char,
children: Seq[Trie] = Nil,
indices: Seq[Int] = Nil) {
def add(word: String,
index: Int): Trie = {
val updatedChildren = word.toSeq match {
case Seq(head) =>
update(head) {
Trie(head, indices = Seq(index))
} { trie =>
trie.copy(indices = trie.indices :+ index)
}
case head +: tail =>
update(head) {
Trie(head).add(tail.mkString, index)
} { trie =>
trie.add(tail.mkString, index)
}
}
copy(children = updatedChildren)
}
private def update(head: Char)
(notFound: => Trie)
(found: Trie => Trie) =
children.partition(_.char == head) match {
case (Nil, tries) => notFound +: tries
case (trie +: _, tries) => found(trie) +: tries
}
def get(word: String): Seq[Int] =
word.toSeq match {
case Seq(head) =>
children.find(_.char == head).map(_.indices).getOrElse(Nil)
case head +: tail =>
children.find(_.char == head).map(_.get(tail.mkString)).getOrElse(Nil)
}
}
assert(
Trie(' ')
.add("hello", 0)
.add("world", 1)
.add("hello", 2)
.get("hello") == Seq(0, 2)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment