如何构建顶级节点及其子节点的映射

时间:2017-01-12 16:01:34

标签: scala

case class Node(id: Int, children: Set[Node])

val topLevel = Node(1, tlChildren)
val topLevel2 = Node(2, tl2Children)

val nodes = Set(topLevel1, topLevel2,..)

我想创建一个topLevel id的地图,并将该值作为孩子们所有id的列表。

val map = Map[Int, List[Int]] = ..

因此,使用此地图,给定任何ID,我可以弄清楚顶级ID是什么。

如何在给定上述Node类和节点层次结构的情况下生成此映射?

我可以像这样获得顶级节点:

val topLevelNodeIds = nodes.map(n => n.id)

但不确定这是否有用,因为我需要在递归调用中使用它。

2 个答案:

答案 0 :(得分:1)

首先,我们将定义用于递归遍历666并收集所有ID的辅助方法:

Node

现在我们可以简单地将每个def collectIds(nodes: Set[Node]): List[Int] = nodes.map(_.id).toList ++ nodes.map(_.children).map(collectIds).flatten 映射到上述方法的结果:

Node

答案 1 :(得分:1)

为了以尾递归方式进行,我们需要使用BFS算法:

case class Node(id: Int, children: Set[Node])

val topLevel = Node(1, Set.empty)
val topLevel2 = Node(2, Set.empty)

val nodes = Set(topLevel, topLevel2)

@tailrec
def tailRecursiveSolution(buffer: List[Node],
                          visited: Set[Node] = Set.empty,
                          acc: Map[Int, List[Int]] = Map.empty): Map[Int, List[Int]] =
  buffer match {
    case top :: bottom if !visited.contains(top) =>
      val children = top.children
      tailRecursiveSolution(
        children.toList ::: bottom,
        visited + top,
        acc + (top.id -> children.map(_.id).toList)
      )
    case top :: bottom =>
      tailRecursiveSolution(bottom, visited, acc)
    case Nil => acc
  }

现在,对于每个级别,我们使用tailRecursiveSolution并获得所需的映射。所以我们需要做的就是从每个级别折叠结果:

val result: Map[Int, List[Int]] = 
      nodes./:(Map.empty[Int, List[Int]]) { case (acc, root) => acc ++ tailRecursiveSolution(List(root)) }