Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm for creating multi-dimensional array

I'm using PHP and I need help with a seemingly simple task with an array.

This is my example array:

$arr = array(
    0  => NULL,
    1  => NULL,
    2  => NULL,
    3  => NULL,
    8  => '2',
    9  => '2',
    10 => '2',
    11 => '2',
    12 => '3',
    13 => '3',
    14 => '8',
    15 => '8',
    16 => '14',
    17 => '14',
    18 => '14'
);

The keys of the array represent the IDs (unique).
The values are the parentIDs, i.e. the ID of the parent "node". NULL means that there is no parentID (i.e. 1st dimension of the new array).

Now, I need to create a new, multi-dimensional array that has all the child elements under their parent IDs. (This probably sounds very confusing, sorry for my lack of descriptive abilities. There's an example below, which should make things clearer)

Here's what the new array of my example would look like after the "sorting" function, or whatever you call this, was applied:

$arr = array(
 0 => array(),
 1 => array(),
 2 => array(
     8 => array(
        14 => array(
            16 => array(),
            17 => array(),
            18 => array()
),
        15 => array()
),
     9 => array(),
    10 => array(),
    11 => array()
),
 3 => array(
    12 => array(),
    13 => array()
)
);

I know all the empty array()s are probably not a very clean and elegant solution but unfortunately this is the way I need it to be!

like image 889
user367217 Avatar asked Nov 06 '22 06:11

user367217


1 Answers

This recursive function will add the given datum to the correct parent, and should be called once for each element in your starting array.

function add_branch(&$tree, $datum, $parent) {

    // First we have the base cases:
    // If the parent is NULL then we don't need to look for the parent
    if ($parent == NULL) {
        $tree[$datum] = array();
        return true;
    }

    // If the array we've been given is empty, we return false, no parent found in this branch
    if (! count($tree)) {
        return false;
    }


    // We loop through each element at this level of the tree...
    foreach($tree as $key => $val) {

        // If we find the parent datum...
        if ($key == $parent) {

            // We add the new array in and we're done.
            $tree[$key][$datum] = array();
            return true;
        }

        // Otherwise, check all the child arrays
        else {

            // Now we check to see if the parent can be found in the curent branch
            // If a recursive call found a parent, we're done
            if (add_branch($tree[$key], $datum, $parent)) {
                return true;
            }
        }
    }

    // If none of the recursive calls found the parent, there's no match in this branch
    return false;

}

The comments are quite verbose, in the hope that you can understand what is going on. I'd encourage you to do a bit of reading on recursive functions to get your head around it.

This is how it would be used:

$arr = array(
 0 => NULL,
 1 => NULL,
 2 => NULL,
 3 => NULL,
 8 =>  '2',
 9 =>  '2',
10 =>  '2',
11 =>  '2',
12 =>  '3',
13 =>  '3',
14 =>  '8',
15 =>  '8',
16 => '14',
17 => '14',
18 => '14'
);


$final = array();

foreach ($arr as $datum => $parent) {
    add_branch($final, $datum, $parent);
}

$final now has the correct finishing array, as indicated in the question.

like image 66
BudgieInWA Avatar answered Nov 09 '22 04:11

BudgieInWA