我有树状结构
class T {
properties:P
children:Seq[T]
}
我希望将它转换为另一个树状结构,其中一些转换应用于属性,而字段用于父节点:
class TT {
properties:PP
parent:TT
children:Seq[TT]
}
无法找到以功能方式执行此操作的方法。你能帮忙吗?
特别是@ om-nom-nom难以想象应该做的工作的java代码:
public class Omnomnom {
static class P {
String value;
}
static class PP {
String value;
}
static class T {
P properties;
List<T> children;
}
static class TT {
PP properties;
TT parent;
List<TT> children;
}
static PP transform_P_into_PP(P properties) {
PP result = new PP();
result.value = properties.value + "pff";
return result;
}
public static TT transform_T_into_TT(T node, TT parent){
TT current = new TT();
current.parent = parent;
current.properties = transform_P_into_PP(node.properties);
List<TT> children = new LinkedList<>();
current.children = children;
for(T child : node.children) {
children.add(transform_T_into_TT(child,current));
}
return current;
}
public static void main(String [] args){
T rootT = new T();
TT rootTT = transform_T_into_TT(rootT,null);
}
}
答案 0 :(得分:5)
我个人认为在这种情况下功能解决方案非常清晰。首先,我将修复您的定义,这些定义无法编译:
// Dummy definitions for the sake of a complete working example.
type P = Int
type PP = String
trait T {
def properties: P
def children: Seq[T]
}
trait TT {
def properties: PP
def parent: Option[TT]
def children: Seq[TT]
}
我所做的一个实质性改变是parent
的类型。根节点没有父节点,如果我们的目标是功能方法,我们不想使用null
,因此我们将其设为可选节点。现在转换定义非常简单:
def transform(f: P => PP)(t: T): TT = {
def transformWithParent(op: Option[TT])(t: T): TT = new TT {
val properties = f(t.properties)
val parent = op
val children: Seq[TT] = t.children.map(transformWithParent(Some(this)))
}
transformWithParent(None)(t)
}
让我们测试一下:
val myTree = new T {
val properties = 3
val children = Seq(
new T {
val properties = 4
val children = Seq.empty
},
new T {
val properties = 5
val children = Seq.empty
}
)
}
val newTree = transform(_.toString)(myTree)
然后例如我们可以查看根的第二个子节点,找到它的父节点(当然是根节点),并获取父节点的值:
scala> newTree.children(1).parent.map(_.properties)
res0: Option[PP] = Some(3)
完全符合预期。