0

I have the following table/PHP array;

 fileid | storage | parent |    name    | is_dir |        last_changed        |   size    | revision 
--------+---------+--------+------------+--------+----------------------------+-----------+----------
      1 |       1 |        | bunny.mov  | f      | 2016-05-17 12:20:45.430934 | 514832018 |      103
      2 |       1 |        | 10mb.bin   | f      | 2016-05-17 12:24:11.291796 |  10000000 |      104
      3 |       1 |        | 10mb.bin   | f      | 2016-05-17 12:28:16.867    |  10000000 |      105
      4 |       1 |        | bunny.mov  | f      | 2016-05-17 12:34:42.191069 | 514832018 |      106
      5 |       1 |        | miep2      | t      | 2016-05-17 12:38:09.286883 |      4096 |      107
      6 |       1 |      5 | bunny.mov  | f      | 2016-05-17 12:38:09.295631 | 514832018 |      107
      7 |       1 |        | miep2      | t      | 2016-05-17 12:48:25.375968 |      4096 |      108
      8 |       1 |      7 | bunany.mov | f      | 2016-05-17 12:48:25.384048 | 514832018 |      108

I would to get this data in an associative array, so I can build a tree-like structure. (file browser of some sorts, where each file has a list of revisions the user can pick)

So far, I have the following code;

private function rebuildStructure($files, $parent)
{
    $result = array();

    foreach ($files as $file){
        $entries = array();
        //get entries with $parent
        foreach ($files as $entry_file){
            if ($entry_file->parent == $file->id){
                array_push($entries, $this->rebuildStructure($files, $entry_file->fileid));
            }
        }
        array_push($result, array(
            'name' => $file->name,
            'entries' => $entries
        ));
    }
    return $result;
}

But this does however not work (infinite loop). Any ideas where I am going wrong? I'd like something along the lines of;

array(
    array( 'name' => 'miep2',
           'entries' => array( ...and repeat... )
    )
)

Any suggestions? Thank you!

1
  • You're calling the method within a for loop on the method, which indeed ends in an infinite loop. Also, why are you giving the $parent parameter to your function if you're not going to use it ;) Commented May 17, 2016 at 16:13

2 Answers 2

2

The intention of this code is to implement the solution in the simplest way, this is not efficient.

This aproach try to find all the children for every element in the array.

private function rebuildStructure($files, $parent)
{
    $result = array();

    foreach ($files as $file) {
        // I'm searching for some childs, and I'm not one of them.
        if (0 != $parent && $parent != $file->parent) continue;

        // I'm a child and we are searching just for "parents"
        if (!empty($file->parent) && 0 == $parent) continue;

        $entries = array();

        // Next nesting level, search for children
        array_push($entries, rebuildStructure($files, $file->fileid));

        array_push($result, array(
            'name' => $file->name,
            'entries' => $entries
        ));
    }

    return $result;
}
Sign up to request clarification or add additional context in comments.

3 Comments

This works wonderfully, thank you @Miguel! What is, in your opinion, a more efficient way?
There is no need to use recursion on this problem and no need to iterate so many times over the array, with just one loop the tree could be done more efficiently.
Even if you do not know how deep it goes?
0

I've come up with this, it should work like you want it to.

private function rebuildStructure($files)
{
    $result = array();

    foreach ($files as $file)
    {
        $entries = array();

        foreach ($files as $entry_file)
        {
            if ($entry_file->parent === $file->id)
            {
                $nestedArray = array();
                array_push($nestedArray, $entry_file);
                array_push($entries, $nestedArray);
            }
        }
        array_push($result, array(
            'name' => $file->name,
            'entries' => $entries
        ));
    }
    return $result;
}

// Call this function to get the tree structure
public function getRebuildedStructure($files)
{
    return rebuildStructure($files);
}

1 Comment

Seems like the original problem was meant to use recursion, in this case two level nesting won't work.

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.