4

I have an array containing full paths of files. Like this:

[0] => "dir1/dir2/dir3/file.ext"
[1] => "dir1/dir2/dir3/file2.ext"
[2] => "dir1/dir2/dir3/file3.ext"
[3] => "dir2/dir4/dir5/file.ext"

I need to parse it and get a multidimensional array, something like this:

[dir1] => [dir2] => [dir3] => file.ext
                           => file2.ext
                           => file3.ext
[dir2] => [dir4] => [dir5] => file.ext

Any ideas? Must work with various depth of the structure.

Havelock
  • 6,500
  • 3
  • 34
  • 41
Koga
  • 135
  • 8
  • 2
    [This question](http://stackoverflow.com/questions/8537148/string-with-array-structure-to-array/8537238) talks about something almost identical to what you need. – Jon Sep 16 '12 at 16:06

2 Answers2

3

To build off of @J. Bruni's answer, the code that you need is the following:

function parse_paths_of_files($array)
{
    rsort($array);

    $result = array();

    foreach ($array as $item) {
        $parts = explode('/', $item);
        $current = &$result;

        for ($i = 1, $max = count($parts); $i < $max; $i++) {

            if (!isset($current[$parts[$i - 1]])) {
                $current[$parts[$i - 1]] = array();
            }

            $current = &$current[$parts[$i - 1]];
        }

        $last = end($parts);

        if (!isset($current[$last]) && $last) {
            // Don't add a folder name as an element if that folder has items
            $current[] = end($parts);
        }
    }

    return $result;
}

J Bruni's answer is dodgy because it assumed values are there that aren't, resulting in a lot of PHP undefined index errors.

This version also prevents a folder name being added to the list if the folder already has an entry to prevent:

$result = [
    0 => folder_name
    folder_name => [
        ...
    ]
]
Luke Madhanga
  • 4,192
  • 1
  • 35
  • 40
2

I've done your homework! :-)

http://ideone.com/UhEwd

Code:

<?php

function parse_paths_of_files($array)
{
    $result = array();

    foreach ($array as $item)
    {
        $parts = explode('/', $item);
        $current = &$result;
        for ($i = 1, $max = count($parts); $i < $max; $i++)
        {
            if (!isset($current[$parts[$i-1]]))
            {
                 $current[$parts[$i-1]] = array();
            }
            $current = &$current[$parts[$i-1]];
        }
        $current[] = $parts[$i];
    }

    return $result;
}

$test = array(
    "dir1/dir2/dir3/file.ext",
    "dir1/dir2/dir3/file2.ext",
    "dir1/dir2/dir3/file3.ext",
    "dir2/dir4/dir5/file.ext"
);

print_r(parse_paths_of_files($test));

?>
J. Bruni
  • 19,262
  • 11
  • 70
  • 90