简体   繁体   English

输出引用表的递归函数

[英]Recursive function that outputs a table of references

Let's say I have an array like this假设我有一个这样的数组

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,),
);

Two "primary keys" which are "id_1" and "id_2", the combination of both cannot be repeated.两个“主键”是“id_1”和“id_2”,两者的组合不能重复。 Each row could be referenced by another using "ref_1" and "ref_2", the referenced row will contain the "id_1" and "id_2" form the referer (father).每一行都可以被另一个使用“ref_1”和“ref_2”引用,被引用的行将包含来自引用者(父)的“id_1”和“id_2”。

Type A rows cannot be referenced.不能引用类型 A 的行。 Type B & C can be referenced by A. Also, B can be referenced from C and vice-versa.类型 B 和 C 可以被 A 引用。此外,B 可以被 C 引用,反之亦然。 The tree is not always complete, it may only have TYPE A and B or TYPE A and C, or just TYPE A.树并不总是完整的,它可能只有 TYPE A 和 B 或 TYPE A 和 C,或者只有 TYPE A。

I'm trying to make a function that returns a table like this:我正在尝试创建一个返回这样的表的函数:

|   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      |               |

Every time a row references 2 (or more) other rows, the data is father's data is splitted and outputs one row for each reference.每次一行引用 2(或更多)其他行时,数据是父亲的数据被拆分并为每个引用输出一行。 If a type A referers 2 type B, and each type B referers other 2 type C, the output table will have 4 rows.如果一个A类引用2个B类,每个B类引用另外2个C类,则输出表将有4行。

There are more than three types, this is just a PoC.不止三种,这只是一个PoC。 I tried to explain this as detailed as possible, but it may be a bit difficult to understand.我试图尽可能详细地解释这一点,但可能有点难以理解。 I know it may have some recursion involved, but I've been trying for the last 8 hours and couldn't make this work.我知道它可能涉及一些递归,但我一直在尝试过去 8 个小时,但无法完成这项工作。

PS: The output could be an array too. PS:输出也可以是一个数组。

If any further information is needed, please let me know.如果需要任何进一步的信息,请告诉我。

Well, finally I got it working.好吧,我终于让它工作了。 I've added some information to make my life easier.我添加了一些信息,让我的生活更轻松。

I've added a flag to each row that says if that row has no childs (so it's the last).我为每一行添加了一个标志,说明该行是否没有孩子(所以它是最后一个)。 The number of "last" rows is the number of rows of the output so I started from there. “最后”行数是输出的行数,所以我从那里开始。

Also, I've added a "key" which is "id_1-id_2" to each row.另外,我在每一行添加了一个“键”,即“id_1-id_2”。

Here is the full code:这是完整的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM