Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更新树继承人结构中的中间节点_C#_Linq_Recursion - Fatal编程技术网

C# 更新树继承人结构中的中间节点

C# 更新树继承人结构中的中间节点,c#,linq,recursion,C#,Linq,Recursion,我有一个包含字符串属性的节点树层次结构。树层次结构包含父级子级和该子级的子级,依此类推。我必须从列表中找到并更新中间一个子项的string属性,还必须更新父项及其子项。比如说, NodeData[] nodes = new NodeData[] { new NodeData { Text = "A", Children = new NodeData[]

我有一个包含字符串属性的节点树层次结构。树层次结构包含父级子级和该子级的子级,依此类推。我必须从列表中找到并更新中间一个子项的string属性,还必须更新父项及其子项。比如说,

 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”后立即提升到父级?是的,我需要您始终可以将父属性放入节点中,以便可以在树上上下移动。在一些项目中,我还制作了一个列表,这样我就可以按顺序访问数据以及一棵树。列表不会复制节点,而是通过引用访问节点,因此对节点的任何更改(包括树和列表)都会得到更新。