代码为给定CSV文件生成baum层次结构的灵活性



我需要借助Baum Library生成层次结构,将CSV文件的内容转换为我网站的层次结构。。。

以下是CSV文件的格式,用户将上传该文件以解析到Baum层次结构中。其中的列表示层次结构的级别。CSV文件屏幕截图

现在我已经将这个CSV文件解析为二维数组($companyDetailsIn2dArray),我编写的代码只支持生成到第三级,我希望它"对任何级别都灵活",即对超过3级的级别。现在,为了做到这一点,我写了一些代码,鼓励我为它编写递归函数,但我很困惑,我应该从哪里开始。我用来存储上次创建的节点的临时变量($lastDeptNodeI; $lastDeptNodeJ; $lastMacNodeI; $lastMacNodeJ)限制了我编写递归函数。。。

请帮我写递归函数,或者建议我用CSV文件获得Baum层次结构的任何其他方法。。。

以下是我的代码。。。

$lastDeptNodeI =-1; //variable used to store array location(row) for last created 1st level node i.e. Dept node
$lastDeptNodeJ =-1; //variable used to store array location(column) for last created 1st level node i.e. Dept node
$lastMacNodeI =-1; //variable used to store array location(row) for last created 2nd level node i.e. Machine node
$lastMacNodeJ =-1; //variable used to store array location(column) for last created 2nd level node i.e. Machine node
$root = Company::create(['name' => $newCompanyName]);   //Creating node
$root->makeRoot();  //Making Root Node
for($i=0;$i<sizeof($companyDetailsIn2dArray);$i++){
    for($j=0;$j<sizeof($companyDetailsIn2dArray[$i]);$j++){
        if($companyDetailsIn2dArray[$i][$j] != "") {
            if ($j == 0) {  //if it is Dept!
                $newNode[$i][$j] = Company::create(['name' => $companyDetailsIn2dArray[$i]{$j}]);
                $newNode[$i][$j]->makeChildOf($root);
                $lastDeptNodeI = $i;
                $lastDeptNodeJ = $j;
                $lastMacNodeI = -1;
                $lastMacNodeJ = -1;
            } elseif ($j == 1) { // if it is machine
                $newNode[$i][$j] = Company::create(['name' => $companyDetailsIn2dArray[$i]{$j}]);
                if($lastDeptNodeI!=-1 || $lastDeptNodeJ!=-1) {
                    $newNode[$i][$j]->makeChildOf($newNode[$lastDeptNodeI][$lastDeptNodeJ]);
                    $lastMacNodeI = $i;
                    $lastMacNodeJ = $j;
                }
                else{
                    $newNode[$i][$j]->makeChildOf($root);
                    $lastMacNodeI = $i;
                    $lastMacNodeJ = $j;
                }
            } elseif ($j == 2)
            { //if it is Meter!
                $newNode[$i][$j] = Company::create(['name' => $companyDetailsIn2dArray[$i]{$j}]);
                if($lastMacNodeI!=-1 || $lastMacNodeJ!=-1){
                    $newNode[$i][$j]->makeChildOf($newNode[$lastMacNodeI][$lastMacNodeJ]);
                }
                elseif($lastDeptNodeI!=-1 || $lastDeptNodeJ!=-1){
                    $newNode[$i][$j]->makeChildOf($newNode[$lastDeptNodeI][$lastDeptNodeJ]);
                    $lastMacNodeI = $i;
                    $lastMacNodeJ = $j;
                }
                else{
                    $newNode[$i][$j]->makeChildOf($root);
                    $lastDeptNodeI = $i;
                    $lastDeptNodeJ = $j;
                    $lastMacNodeI = -1;
                    $lastMacNodeJ = -1;
                }
            }
        }
    }
}
echo "File parsed Successfully!";

我认为您可以以深度优先搜索的方式添加节点,当您找到一个节点时,也可以添加子节点。

如果你想进行完全递归,你需要2个递归函数:

  1. 第一个是向树中添加节点的函数,但是添加节点后,它将找到其所有子节点(向下1级)节点,并为这些节点调用自己

这个函数的签名可能看起来像这样:addNode(parent_node,i_of_current_node,j_of_current_nod,content_of_ccurrent_node)

递归在没有子级时结束。

我也会编写一个助手函数来查找节点的子节点。您只需查找与j_of_current_node具有相同j的下一个非空单元格,并从i_of_current_node+1和i_of_next_node之间获取非空单元格。

  1. 第二个递归函数将读取companyDetailsIn2dArray逐列

此函数的签名可能类似于:读取列(j_of_current_column,i_of_first_node_in_prev_column)

当j_of_current_column大于数组的大小时,递归结束。


当您阅读一列时,您可以为每个非空单元格调用addNode函数,如下所示:addNode($root,$i,$j,$companyDetailsIn2dArray[$i][$j])addNode在根下创建新节点,找到子节点,然后为addNode($newNode、$childI、$childJ、$companyDetailsIn2dArray[$childI][$childJ])等子节点调用自己。

这样,一旦读取了第一列,就可以在第一列中第一个非空单元格的$i下添加文件中的每个节点。通过调用readColumn(0,i_size_of_array)处理第一列

在处理任何后续列时(与第一列相同),您只能读取它,直到到达前一列中第一个非空单元格的i,因为您已经添加了具有更高i索引的节点,因为这些节点在前一列具有父节点。通过调用readColumn(j_of_current_column+1,i_of_first_node_in_current_column)处理第一个列之后的列。

最新更新