递归函数,输出引用表

时间:2016-09-13 13:43:04

标签: php recursion reference

让我们说我有一个像这样的数组

Array(
    Array("id_1" => 1,"id_2" => 1,"name" => "test1","type" => "A","ref_1" => 0,"ref_2" => 0,),
    Array("id_1" => 1,"id_2" => 2,"name" => "test2","type" => "B","ref_1" => 1,"ref_2" => 1,),
    Array("id_1" => 1,"id_2" => 3,"name" => "test3","type" => "B","ref_1" => 1,"ref_2" => 1,),
    Array("id_1" => 2,"id_2" => 1,"name" => "test4","type" => "B","ref_1" => 1,"ref_2" => 1,),
    Array("id_1" => 2,"id_2" => 3,"name" => "test5","type" => "C","ref_1" => 1,"ref_2" => 2,),
    Array("id_1" => 2,"id_2" => 15,"name" => "test6","type" => "C","ref_1" => 1,"ref_2" => 3,),
    Array("id_1" => 5,"id_2" => 22,"name" => "test7","type" => "B","ref_1" => 4,"ref_2" => 9,),
    Array("id_1" => 4,"id_2" => 9,"name" => "test8","type" => "C","ref_1" => 1,"ref_2" => 1,),
    Array("id_1" => 1,"id_2" => 7,"name" => "test9","type" => "C","ref_1" => 2,"ref_2" => 1,),
    Array("id_1" => 5,"id_2" => 20,"name" => "test10","type" => "B","ref_1" => 4,"ref_2" => 9,),
    Array("id_1" => 5,"id_2" => 5,"name" => "test11","type" => "B","ref_1" => 4,"ref_2" => 9,),
    Array("id_1" => 5,"id_2" => 4,"name" => "test12","type" => "B","ref_1" => 1,"ref_2" => 1,),
);

两个"主键"这是" id_1"和" id_2",两者的组合不能重复。每一行都可以使用" ref_1"和" ref_2",引用的行将包含" id_1"和" id_2"形成引用者(父亲)。

无法引用A类行。 B型和B型C可以由A引用。另外,B可以从C引用,反之亦然。树并不总是完整的,它可能只有TYPE A和B或TYPE A和C,或者只有TYPE A.

我试图创建一个返回如下表格的函数:

|   TYPE A NAME |   TYPE B NAME |   TYPE C NAME |
|   ------------------------------------------- |
|   test1       |   test2       |   test5       |
|   test1       |   test3       |   test6       |
|   test1       |   test7       |   test8       |
|   test1       |   test4       |   test9       |
|   test1       |   test10      |   test8       |
|   test1       |   test11      |   test8       |
|   test1       |   test12      |               |

每当一行引用2个(或更多)其他行时,数据就会被父数据分割,并为每个引用输出一行。如果类型A引用2类型B,并且每个类型B引用其他2类型C,则输出表将具有4行。

有三种以上的类型,这只是一个PoC。我试图尽可能详细地解释这一点,但可能有点难以理解。我知道它可能会涉及一些递归,但我在过去的8个小时内一直在努力,但是无法完成这项工作。

PS:输出也可以是数组。

如果需要进一步的信息,请告诉我。

1 个答案:

答案 0 :(得分:1)

好吧,最后我开始工作了。我添加了一些信息,让我的生活更轻松。

我在每一行都添加了一个标志,表示该行是否没有子节点(所以它是最后一行)。 “last”行的数量是输出的行数,所以我从那里开始。

另外,我已经为每一行添加了一个“密钥”,即“id_1-id_2”。

以下是完整代码:

$Adata = Array(
    "1-1" =>    Array("id_1" => 1,"id_2" => 1,"name" => "test1",    "type" => "A","ref_1" => 0,"ref_2" => 0,"last" => false),
    "1-2" =>    Array("id_1" => 1,"id_2" => 2,"name" => "test2",    "type" => "B","ref_1" => 1,"ref_2" => 1,"last" => false),
    "1-3" =>    Array("id_1" => 1,"id_2" => 3,"name" => "test3",    "type" => "B","ref_1" => 1,"ref_2" => 1,"last" => false),
    "2-1" =>    Array("id_1" => 2,"id_2" => 1,"name" => "test4",    "type" => "B","ref_1" => 1,"ref_2" => 1,"last" => false),
    "2-3" =>    Array("id_1" => 2,"id_2" => 3,"name" => "test5",    "type" => "C","ref_1" => 1,"ref_2" => 2,"last" => true),
    "2-15" =>   Array("id_1" => 2,"id_2" => 15,"name" => "test6",   "type" => "C","ref_1" => 1,"ref_2" => 3,"last" => true),
    "5-22" =>   Array("id_1" => 5,"id_2" => 22,"name" => "test7",   "type" => "B","ref_1" => 4,"ref_2" => 9,"last" => true),
    "4-9" =>    Array("id_1" => 4,"id_2" => 9,"name" => "test8",    "type" => "C","ref_1" => 1,"ref_2" => 1,"last" => false),
    "1-7" =>    Array("id_1" => 1,"id_2" => 7,"name" => "test9",    "type" => "C","ref_1" => 2,"ref_2" => 1,"last" => true),
    "5-20" =>   Array("id_1" => 5,"id_2" => 20,"name" => "test10",  "type" => "B","ref_1" => 4,"ref_2" => 9,"last" => true),
    "5-5" =>    Array("id_1" => 5,"id_2" => 5,"name" => "test11",   "type" => "B","ref_1" => 4,"ref_2" => 9,"last" => true),
    "5-4" =>    Array("id_1" => 5,"id_2" => 4,"name" => "test12",   "type" => "B","ref_1" => 1,"ref_2" => 1,"last" => true),
);

$Atable = Array();
foreach ($Adata as $key=>$data){
    if (!$data['last']){
        continue;
    }
    $output = Array('A'=>'','B'=>'','C'=>'');
    echo "SAVE {$data['type']} - {$data['name']}<br>";
    $output[$data['type']] = $data['name'];

    $referer = $data;
    do {
        $referer = $Adata["{$referer['ref_1']}-{$referer['ref_2']}"];
        $output[$referer['type']] = $referer['name'];
    } while (!empty($referer['ref_1']) && !empty($referer['ref_2']));

    $Atable[] = $output;
}

foreach ($Atable as $row){
    echo "{$row['A']}-{$row['B']}-{$row['C']}<br>";
}