3

I have this code here which gives me the result I'm looking for, a nicely formatted tree of values.

    $todos = $this->db->get('todos'); //store the resulting records
    $tree = array();                  //empty array for storage
    $result = $todos->result_array(); //store results as arrays

    foreach ($result as $item){
        $id = $item['recordId'];
        $parent = $item['actionParent'];
        $tree[$id] = isset($tree[$id]) ? $item + $tree[$id] : $item;
        $tree[$parent]['_children'][] = &$tree[];
    }

    echo '<pre>';
    print_r($tree);
    echo '</pre>';

When I put the code from the foreach into a function like so, I get an empty array. What am I missing?

    function adj_tree($tree, $item){
        $id = $item['recordId'];
        $parent = $item['actionParent'];
        $tree[$id] = isset($tree[$id]) ? $item + $tree[$id] : $item;
        $tree[$parent]['_children'][] = &$tree[];
    }

    $todos = $this->db->get('todos'); //store the resulting records
    $tree = array();                  //empty array for storage
    $result = $todos->result_array(); //store results as arrays

    foreach ($result as $item){
        adj_tree($tree, $item);
    }

    echo '<pre>';
    print_r($tree);
    echo '</pre>';
0

3 Answers 3

5

The easiest way is to pass the $tree to the function by reference. Consider changing the following line in your code

function adj_tree($tree, $item)

to

function adj_tree(&$tree, $item)

This is because in your code $tree is being passed inside the function adj_tree as a copy of the original $tree. When you pass by reference the original one is passed and the changes in it by the function adj_tree are reflected after the call.

A second (not preferred) alternative is for your function to return the modified tree so your function will look as follows:

function adj_tree($tree, $item) {
        $id = $item['recordId'];
        $parent = $item['actionParent'];
        $tree[$id] = isset($tree[$id]) ? $item + $tree[$id] : $item;
        $tree[$parent]['_children'][] = &$tree[];
        return $tree; // this is the line I have added
}

And your foreach loop will be like this:

foreach ($result as $item){
    $tree = adj_tree($tree, $item);
}
Sign up to request clarification or add additional context in comments.

Comments

3

Right now the function is making a local copy of {$tree}, editing it and then discarding that copy when the function closes.

You have two options:

1) return the local copy of {$tree} and assign it to the global copy.

function adj_tree($tree, $item){
    $id = $item['recordId'];
    $parent = $item['actionParent'];
    $tree[$id] = isset($tree[$id]) ? $item + $tree[$id] : $item;
    $tree[$parent]['_children'][] = &$tree[];
    return $tree;
}
//...
foreach ($result as $item){
    $tree = adj_tree($tree, $item);
}

2) pass the array by reference and edit the global version within the function.

function adj_tree(&$tree, $item){
    $id = $item['recordId'];
    $parent = $item['actionParent'];
    $tree[$id] = isset($tree[$id]) ? $item + $tree[$id] : $item;
    $tree[$parent]['_children'][] = &$tree[];
}

Comments

0

try this:

function adj_tree($tree, $item){
    global $tree;
    // ...

or

function adj_tree(&$tree, $item){

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.