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

时间:2016-04-06 18:46:44

标签: php laravel csv recursion hierarchy

我需要在Baum图书馆生成层次结构的帮助下,将CSV文件的内容转换为我网站的层次结构...

以下是用户将上传以解析为Baum Hierarchy的CSV文件的格式。其中的列表示层次结构的级别。 CSV File Screenshot

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

请帮我写一个递归函数或建议我用CSV文件获取Baum Hierarchy的任何其他方法......

以下是我的代码......

$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!";

1 个答案:

答案 0 :(得分:1)

我认为你可以通过深度优先搜索的方式添加节点,当你发现节点也添加子节点时。

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

  1. 第一个是将节点添加到树中的函数,但是 添加一个节点后,它会找到它的所有子节点(1级向下) 节点,并为那些自称。
  2. 此函数的签名可能如下所示:addNode(parent_node,i_of_current_node,j_of_current_node,content_of_current_node)

    当没有孩子时递归结束。

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

    1. 第二个递归函数将读取companyDetailsIn2dArray 逐列。
    2. 此功能的签名可能类似于: readColumn(j_of_current_column,i_of_first_node_in_prev_column)

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

      当你读到一个列时,你会为每个空单元格调用你的addNode函数,如下所示:addNode($ root,$ i,$ j,$ companyDetailsIn2dArray [$ i] [$ j]) addNode在root下创建新节点,找到子节点,然后为子节点调用自己,如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)来处理第一列之后的列。