skip to Main Content

I have a bunch of name-parentname pairs, that I turned into a heirarchical tree structure. So for example, these are my pairings:

Child : Parent
H : G
F : G
G : D
E : D
A : E
B : C
C : E
D : 0

Which after using this function found here.

$array = array('H' => 'G', 'F' => 'G', ..., 'D' => null);
function to_tree($array)
{
    $flat = array();
    $tree = array();

    foreach ($array as $child => $parent) {
        if (!isset($flat[$child])) {
            $flat[$child] = array();
        }
        if (!empty($parent)) {
            $flat[$parent][$child] =& $flat[$child];
        } else {
            $tree[$child] =& $flat[$child];
        }
    }

    return $tree;
}

$array_tree = to_tree($array)

I get an array like this:

Array
(
    [7] => Array
        (
            [24] => Array
                (
                )

            [38] => Array
                (
                )

            [78] => Array
                (
                )

            [103] => Array
                (
                )

            [121] => Array
                (
                )

            [163] => Array
                (
                    [162] => Array
                        (
                        )

                    [213] => Array
                        (
                        )

                    [214] => Array
                        (
                        )

                    [215] => Array
                        (
                        )

                )
      ...

What I need is to get an array of the key i’m looking for plus all the children keys.
Let’s say I’m looking for key 7, so I would get an array like this one:

Array
(
    [0] => 7
    [1] => 24
    [2] => 38
    [3] => 78
    [4] => 103
    [5] => 121
    [6] => 163
    [7] => 162
    [8] => 213
    [9] => 214
    [10] => 215
    ...
)

But I also need to look on keys like 163 and get:

Array
(
    [0] => 163
    [1] => 162
    [2] => 213
    [3] => 214
    [4] => 215
)

I think is not that hard for experienced users, but I can’t quite figure it out.

2

Answers


  1. Chosen as BEST ANSWER

    After digging a lot I came up with this solution:

    function get_children($needle, array $haystack, array &$result = null, $found = false) {
        // This is to initialize the result array and is only needed for
        // the first call of this function
        if (is_null($result)) {
            $result = [];
        }
        foreach ($haystack as $key => $value) {
            // Check whether the key is the value we are looking for. If the value
            // is not an array, add it to the result array.
            if ($key === $needle && empty($value)) {
                //key found but has no children, so lets add the key to the result.
                $result[] = $key;
            }
            elseif ($key === $needle && !empty($value)) {
                // key found and it has children so let's find all the children.
                $result[] = $key;
                get_children(null, $value, $result, true);
            }
            elseif ($found && empty($value)) {
                // If key found then we add the children.
                $result[] = $key;
            }
            elseif ($found && !empty($value)) {
                // If key found but children has more children then were looking for them.
                $result[] = $key;
                get_children(null, $value, $result, true);
            }
            elseif (!empty($value)) {
                // If we haven't found the key, we keep looking through subarrays.
                get_children($needle, $value, $result, false);
            }
        }
        return $result;
    }
    

    This is working great, I don't know if it's the best solution.


  2. <?php
    
        $data = array(
            'H' => 'G',
            'F' => 'G',
            'G' => 'D',
            'E' => 'D',
            'A' => 'E',
            'B' => 'C',
            'C' => 'E',
            'D' => '0'
        );
    
        $root_node = 'G'; // Change the root node here.
    
        $parents_with_children = array();
    
        // 1) First create a data structure with parents and children.
        foreach($data as $child => $parent){
            if(!isset($parents_with_children[$parent])){
                $parents_with_children[$parent] = array();
            }
            $parents_with_children[$parent][] = $child;
        }
    
        // 2) Then call a recursive function to find the tree structure, from a specific root node
        find_children($root_node, $parents_with_children);
    
        function find_children($root_node, $parents_with_children){
            echo '<br>Parent:'.$root_node;
            $found_children = array();
            foreach($parents_with_children as $parent => $children){
                if($parent === $root_node){
                    foreach($children as $child){
                        if(!in_array($child, $found_children)){
                            echo '<br>- Child:'.$child;
                            $found_children[] = $child;
                        }
                    }
                }
            }
    
            foreach($found_children as $child){
                find_children($child, $parents_with_children);
            }
        } // find_children
    
    ?>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search