All Downloads are FREE. Search and download functionalities are using the official Maven repository.

izumi.fundamentals.collections.WildcardPrefixTree.scala Maven / Gradle / Ivy

package izumi.fundamentals.collections

import izumi.fundamentals.collections
import izumi.fundamentals.collections.WildcardPrefixTree.PathElement

case class WildcardPrefixTree[K, V](values: Seq[V], children: Map[PathElement[K], WildcardPrefixTree[K, V]]) {
  def findSubtrees(prefix: List[K]): Seq[WildcardPrefixTree[K, V]] = {
    prefix match {
      case Nil =>
        Seq(this)
      case head :: tail =>
        val exact = children.get(PathElement.Value(head))
        val wildcard = children.get(PathElement.Wildcard)
        (exact.toSeq ++ wildcard.toSeq).flatMap(_.findSubtrees(tail))
    }
  }

  def subtreeValues: Seq[V] = {
    values ++ children.values.flatMap(_.subtreeValues)
  }
}

object WildcardPrefixTree {
  sealed trait PathElement[+V]
  object PathElement {
    case class Value[V](value: V) extends PathElement[V]
    case object Wildcard extends PathElement[Nothing]
  }

  def build[P, V](pairs: Seq[(Seq[Option[P]], V)]): WildcardPrefixTree[P, V] = {
    val (currentValues, subValues) = pairs.partition(_._1.isEmpty)

    val next = subValues
      .collect {
        case (k :: tail, v) =>
          (k, (tail, v))
      }
      .groupBy(_._1)
      .toSeq
      .map {
        case (k, group) =>
          val wk: PathElement[P] = k match {
            case Some(value) =>
              PathElement.Value(value)
            case None =>
              PathElement.Wildcard
          }
          wk -> build(group.map(_._2))
      }
      .toMap

    collections.WildcardPrefixTree(currentValues.map(_._2), next)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy