1

I am trying to find a way to create an array of directories. But as we all know directories can have many subDirs and those subDirs can have more subDir and so on and on. The directories length are unknown as it can change.

Say I have a directory as www/webs/apps/pics and another www/webs/test.

The idea would be to have an array such as: (yes the below is json, i just converted it in my php demonstration because i find it easier to read)

{
  "www": {
     "webs": {
         "apps": {
            "pics": "Im Here"
             }
         },
       "test": "im Here too"
     }
}

There is no relation from the above output to the below code. The below code is here just to give an idea what I need.

$exploedDir = explode("/", $unsortedDir);
foreach ($exploedDir as $dir){
    $this->allDirectiroesFound[$dir] = $dir;
}

How can I make $this->allDirectiroesFound has as many dimensions as it is needed without knowing the length of the directory, I cant hard code $this->allDirectiroesFound[][][][][][] it as next time around the array length might be [][][].

5
  • 2
    Usually once you start to want more than "just arrays", it's time to pick a better datastructure. In this case, what you really want is a tree, not "an array of arrays of arrays of arrays of ..." Commented Aug 12, 2019 at 22:37
  • 1
    I think the question I linked should handle this perfectly for you. Here's a working example with your example paths: 3v4l.org/PEBrL Commented Aug 12, 2019 at 23:17
  • @Don'tPanic thanks Commented Aug 13, 2019 at 18:34
  • @Don'tPanic could explain the pass by reference bit? why does the second foreach loop needs this temp as pass by reference &$temp[$key];? thanks Commented Aug 13, 2019 at 20:58
  • Normally PHP will pass everything by value. If you assign $temp = $temp[$key]; without the reference, then $temp just takes the value of $temp[$key], which is null because it hasn't been set to any value yet. With the reference assignment, $temp points to $temp[$key] instead of taking its value so you're able to continue to add nested keys. Commented Aug 13, 2019 at 21:23

2 Answers 2

1

You can just reverse each of the path arrays and then go on creating the Keys from the last directory.

$paths = [
    'www/webs/apps/pics',
    'www/webs/test',
];

$finalArray = [];
foreach($paths as $path){
    $revArr = array_reverse(explode("/", $path)); // This is the trick. Start to build from inside out.
    $pathArray = [];
    foreach($revArr as $key){
            $tempBucket = $pathArray;
            $pathArray = []; // Create fresh empty array to hold the 
            $pathArray[$key] = $tempBucket;
    }

    $finalArray = array_merge_recursive($pathArray, $finalArray); // Recursively Merge the array into the main array
}

echo "<pre>";
print_r(json_encode($finalArray, JSON_PRETTY_PRINT));
echo "</pre>";

DEMO

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks this is a good way of doing I never used array_reverse before so its something nice to learn :)
Indeed it is, then there are more optimal solutions as suggested by the community which this questions is a duplicate of. I just wrote this code off the top of my head in 5 mins :) I myself learned a new thing in this endeavour, viz. Accessing a non existent array key by reference will create it!! Like Wow!!! I guess, everyone's learning new things here.
0

I guess you would need to use arrays of arrays to solve this.

e.g.

var directories = ["base"];
var subdir1 = ["subdir1"];
var subsubdir1 = ["subsubdir1"];
var subsubdir1 = ["subsubdir2"];

subdir.push(subsubdir1);
subdir.push(subsubdir2);
directories.push(subdir1);

so this forms a base->subdir1->[subsubdir1, subsubdir2] structure. The complication comes in ensuring that every 'push' you perform is an array to allow adjacent siblings to exist for that particular sub-directory. That and keeping track of the directory structure

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.