skip to Main Content

I have a table of two columns id and parent_id

|-id-|-parent_id-|
| 1  | 0         |
| 2  | 1         |
| 3  | 16        |
| 4  | 19        |
| 5  | 19        |
| 6  | 2         |
| 7  | 2         |
| 8  | 6         |
| 9  | 19        |
| 10 | 4         |
| 11 | 4         |
| 12 | 2         |
| 13 | 19        |
| 14 | 13        |
| 15 | 2         |
| 16 | 19        |
| 17 | 13        |
| 18 | 19        |
| 19 | 1         |
|-id-|-parent_id-|

I am trying to get all the children recursively

So what I made a function getRecursiveChildren() to check each id and if this id has children I push them to an array BUT for some reason this is not working!

here is my code:

<?php

    $passed_parent_id=1;

    $q = mysqli_query($link, "SELECT * FROM `_del_test` WHERE `isActive` = '1' AND `parent_id` = '$passed_parent_id'");
    if($q&&mysqli_num_rows($q)>0)
    {
        # get all kids
        while($qr=mysqli_fetch_assoc($q))
        {
            $sys_id = $qr['sys_id'];
            $parent_id = $qr['parent_id'];
            getRecursiveChildren($sys_id,$parent_id);
        }
    }


    function getRecursiveChildren($id, $items): array
    {
        $kids = [];
        foreach ($items as $key => $item) {
            if ($item['parent_id'] === $id) {
                $kids[] = $key;

                if ($id !== $key) {
                    array_push($kids, ...getRecursiveChildren($key, $items));
                }
            }
        }
        return $kids;
    }
?>

Could you please help?! my brain is stuck, and I can’t think straight anymore
Thanks

2

Answers


  1. This will create an array in the order of item > child > child > item > item > item > child > item:

    $input = [
      [ 'id' => 1, 'parent_id' => 0 ],
      [ 'id' => 2, 'parent_id' => 1 ],
      [ 'id' => 3, 'parent_id' => 16 ],
      [ 'id' => 4, 'parent_id' => 19 ],
      [ 'id' => 5, 'parent_id' => 19 ],
      [ 'id' => 6, 'parent_id' => 2 ],
      [ 'id' => 7, 'parent_id' => 2 ],
      [ 'id' => 8, 'parent_id' => 6 ],
      [ 'id' => 9, 'parent_id' => 19 ],
      [ 'id' => 10, 'parent_id' => 4 ],
      [ 'id' => 11, 'parent_id' => 4 ],
      [ 'id' => 12, 'parent_id' => 2 ],
      [ 'id' => 13, 'parent_id' => 19 ],
      [ 'id' => 14, 'parent_id' => 13 ],
      [ 'id' => 15, 'parent_id' => 2 ],
      [ 'id' => 16, 'parent_id' => 19 ],
      [ 'id' => 17, 'parent_id' => 13 ],
      [ 'id' => 18, 'parent_id' => 19 ],
      [ 'id' => 19, 'parent_id' => 1 ]
    ];
    
    function extractChildren(array $array, int $parent_id): array {
      return
        array_merge(
          ...array_map(
            fn($item) => [ $item['id'], ...extractChildren($array, $item['id']) ],
            array_filter($array, fn($item) => $item['parent_id'] === $parent_id)
          )
        );
    }
    
    $result = extractChildren($input, 19);
    
    print_r($result);
    

    From inside to outside:

    • array_filter removes the items where ‘parent_id’ does not match.
    • array_map takes the ‘id’ part from an item, and also gets the items children by calling extractChildren recursively.
    • array_merge with the spread operator flattens the result.

    Output:

    Array
    (
      [0] => 4
      [1] => 10
      [2] => 11
      [3] => 5
      [4] => 9
      [5] => 13
      [6] => 14
      [7] => 17
      [8] => 16
      [9] => 3
      [10] => 18
    )
    
    Login or Signup to reply.
  2. You can use array_filter to extract all items that have a specific parent. And then you loop over those extracted items again, and do the same thing recursively.

    Take note that this function does not return only the child IDs, it still returns the [child, parent] tuples – necessary for it to work. But you can then use array_column to extract only the child IDs, if you want.

    $data = json_decode('[[1,0],[2,1],[3,16],[4,19],[5,19],[6,2],[7,2],[8,6],[9,19],[10,4],
                      [11,4],[12,2],[13,19],[14,13],[15,2],[16,19],[17,13],[18,19],[19,1]]');
    
    function getRecursiveChildren($id, $items) {
        $res = array_filter($items, function($item) use ($id) {
           return $item[1] === $id;
        });
        foreach($res as $item) {
            $res += getRecursiveChildren($item[0], $items);
        }
        return $res;
    }
    
    print_r(array_column(getRecursiveChildren(19, $data), 0));
    

    Result:

    Array
    (
        [0] => 4
        [1] => 5
        [2] => 9
        [3] => 13
        [4] => 16
        [5] => 18
        [6] => 10
        [7] => 11
        [8] => 14
        [9] => 17
        [10] => 3
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search