C# 更新树继承人结构中的中间节点
我有一个包含字符串属性的节点树层次结构。树层次结构包含父级子级和该子级的子级,依此类推。我必须从列表中找到并更新中间一个子项的string属性,还必须更新父项及其子项。比如说,C# 更新树继承人结构中的中间节点,c#,linq,recursion,C#,Linq,Recursion,我有一个包含字符串属性的节点树层次结构。树层次结构包含父级子级和该子级的子级,依此类推。我必须从列表中找到并更新中间一个子项的string属性,还必须更新父项及其子项。比如说, NodeData[] nodes = new NodeData[] { new NodeData { Text = "A", Children = new NodeData[]
NodeData[] nodes = new NodeData[]
{
new NodeData
{
Text = "A",
Children = new NodeData[]
{
new NodeData {
Text = "C",
Children = new NodeData[]
{
new NodeData {Text = "AB" }
}
},
new NodeData { Text = "D" },
}
},
new NodeData
{
Text = "B",
Children = new NodeData[]
{
new NodeData
{
Text = "E",
Children = new NodeData[]
{
new NodeData { Text = "F" },
}
}
}
}
};
在这种情况下,我必须找到文本为“AB”的节点,然后更新节点“AB”,但也要更新文本为“D”、“C”和“A”的节点数据。我不知道该怎么做,我想保留一个列表,然后运行该列表来更新相关字段。以下是我的解决方案 给定如下所示的树:
A
C
AB
AC
D
B
E
F
FindAndUpdateAscendingly(nodes, "AB", node =>
{
node.Text += " - processed";
Console.WriteLine(node.Text);
});
鉴于需要更新针节点的所有直接同级节点和所有父节点(包括其同级节点),以下是我的代码:
使用系统;
使用System.Linq;
名称空间Ns
{
内部静态类程序
{
私有静态void Main(字符串[]args)
{
var nodes=new[]
{
新NodeData(“A”,
新节点数据(“C”,
新节点数据(“AB”),
新节点数据(“AC”),
新节点数据(“D”),
新的NodeData(“B”,
新NodeData(“E”,
新节点数据(“F”))
};
FindUpdateAscendingly(节点,“AB”,x=>Console.WriteLine(x.Text));
}
私有静态void FindAndUpdateAscendingly(NodeData[]rootNodes,string dataToFind,Action回调)
{
布尔FindAndAscend(节点数据[]节点)
{
var needleIsFound=nodes.Any(x=>x.Text==dataToFind | | find和ascend(x.Children));
如果(发现针头)
{
foreach(节点中的var nodeData)
{
回调(nodeData);
}
}
未发现返回标记;
}
FindAndAscend(根节点);
}
}
内部类节点数据
{
公共节点数据(字符串文本,参数NodeData[]子项)
{
文本=文本;
Children=Children??Array.Empty();
}
公共字符串文本{get;}
公共节点数据[]子项{get;}
}
}
它的要点在于查找并不断更新函数。向它传递一个节点数组、一个要查找的字符串和一个要在每个要更新的节点上调用的函数
目前,我正在传递一个控制台.WriteLine
作为一个伪“更新”函数,只是为了说明迭代顺序。以下是打印的节点迭代顺序:
AB
AC
C
D
A
B
基本上,它使用指定的文本搜索节点,然后弹出并调用所有父节点及其兄弟节点上的回调。这就是为什么不触摸E
和F
节点的原因
对于实际数据和实际使用,您不需要传递Console.WriteLine
,而是传递一个函数,该函数实际上对NodeData做了一些事情。例如,像这样:
A
C
AB
AC
D
B
E
F
FindAndUpdateAscendingly(nodes, "AB", node =>
{
node.Text += " - processed";
Console.WriteLine(node.Text);
});
如果在“AB”级别上有一个同级节点,比如说“AC”,您还需要更新它吗?或者您需要在找到“AB”后立即提升到父级?是的,我需要您始终可以将父属性放入节点中,以便可以在树上上下移动。在一些项目中,我还制作了一个列表,这样我就可以按顺序访问数据以及一棵树。列表不会复制节点,而是通过引用访问节点,因此对节点的任何更改(包括树和列表)都会得到更新。