请考虑以下标准类:
class Node(val data: NodeData, val children: Seq[Node])
NodeData
类也很简单:
case class NodeData(text: String, foo: List[Bar])
此外,树具有任意深度,它不是固定的。
很显然,对于惯用的Scala,在该结构上执行呼吸优先或深度优先搜索是微不足道的。但是,请考虑我不仅要访问这些节点中的每个节点,而且还希望在每次访问时对它们进行突变。更具体地说,我想对那个foo
列表中的对象进行突变。我将如何实施呢?我想到的一种方法是在遍历节点时以某种方式更新节点并构建新树,但是我的直觉告诉我,有一个比这更简单的解决方案。
答案 0 :(得分:1)
如果您真的想保持不变,则可以在recMap
上定义一个函数Node
,如下所示:
def recMap(f: NodeData => NodeData) : Node = Node(f(data), children.map(_.recMap(f)))
然后您可以像本示例中一样使用它(我也将Node
设置为案例类):
type Bar = Int
case class NodeData(text: String, foo: List[Bar])
case class Node(data: NodeData, children: Seq[Node]) {
def recMap(f: NodeData => NodeData) : Node = Node(f(data), children.map(_.recMap(f)))
}
val tree = new Node(NodeData("parent", List(1, 2, 3, 4)), Seq(
Node(NodeData("a child", List(5, 6, 7, 8)), Seq.empty),
Node(NodeData("another child", List(9, 10, 11, 12)), Seq.empty)
))
val modifiedTree = tree.recMap(
data => NodeData(
if(data.text == "parent") "I am the parent!" else "I am a child!",
data.foo.filter(_ % 2 == 0)
)
)
println(modifiedTree)
也许这就是您要搜索的内容。