6

Let's say I have this string which I want to put in a multidimensional array.

Edit : The number of subfolders in the string are dynamic .. from zero sub folders to 10

<?php
       $string ="Folder1/Folder2/Folder3/filename1\n";
       $string .=" Folder1/Folder2/Folder3/filename2\n";
       $string .=" Folder4/Folder2/Folder3/filename3\n";
?>

I want the following array returned

<?php
 Array
(
    [Folder1] => Array
        (
            [Folder2] => Array
                (
                    [Folder3] => Array
                        (
                            [0] => filename1
                            [1] => filename2
                        )

                )

        )

    [Folder4] => Array
        (
            [Folder2] => Array
                (
                    [Folder3] => Array
                        (
                            [0] => filename3
                        )

                )

        )

)
?>

What would be the most efficient way to accomplish this ?

And for the fun of it let's say this array will be send to the other side of the world and it wants to return to a string. How would we do that ?

Sumit Bijvani
  • 8,154
  • 17
  • 50
  • 82
Paolo_Mulder
  • 1,233
  • 1
  • 16
  • 28
  • Well, if you have a string, and you ultimately want a string, why would you want an array? – Madara's Ghost Apr 12 '12 at 12:32
  • possible duplicate of [String with array structure to Array](http://stackoverflow.com/questions/8537148/string-with-array-structure-to-array) – Jon Apr 12 '12 at 12:41
  • Because some would like to output it as array , and some would like to save it as a string in DB. Sending both would be an option, but is not very efficient. – Paolo_Mulder Apr 12 '12 at 12:48
  • @Paolo_Mulder Please post your desired output when you have a pathless filename in your input string. This is an interesting question, but I think you need to have an all-encompassing parent array to hold pathless filenames. Here is what I am kicking around: https://3v4l.org/UGK0l – mickmackusa Apr 06 '18 at 05:12

3 Answers3

12

You could borrow pieces of code from this class (link no longer available), specifically the _processContentEntry method.

Here's a modified version of the method that does the job:

function stringToArray($path)
{
    $separator = '/';
    $pos = strpos($path, $separator);

    if ($pos === false) {
        return array($path);
    }

    $key = substr($path, 0, $pos);
    $path = substr($path, $pos + 1);

    $result = array(
        $key => stringToArray($path),
    );

    return $result;
}

The output of

var_dump(stringToArray('a/b/c/d'));

Will be

array(1) {
  ["a"]=>
  array(1) {
    ["b"]=>
    array(1) {
      ["c"]=>
      array(1) {
        [0]=>
        string(1) "d"
      }
    }
  }
}

I suppose that's what you need :)


UPDATE

As per your comment, here's how you can process a string separated by new line characters:

$string = "Folder1/Folder2/Folder3/filename1\n";
$string .= " Folder1/Folder2/Folder3/filename2\n";
$string .= " Folder4/Folder2/Folder3/filename3\n";

// split string into lines
$lines = explode(PHP_EOL, $string);

// trim all entries
$lines = array_map('trim', $lines);

// remove all empty entries
$lines = array_filter($lines);

$output = array();

// process each path
foreach ($lines as $line) {
    // split each line by /
    $struct = stringToArray($line);

    // merge new path into the output array
    $output = array_merge_recursive($output, $struct);
}

print_r($output);

P.S. To convert this array to a string, just call json_encode, however I see no reason to convert it to an array and then back to what it was.

Andris
  • 5,853
  • 3
  • 28
  • 34
  • This will return a different array. My example do not contain 3 strings but 1 string composed of 3 lines. Try it yourself. But thanks for pointing in the right direction. – Paolo_Mulder Apr 12 '12 at 12:45
  • Added code to process your multi-line strings. Now it outputs the exact same array as you need. – Andris Apr 13 '12 at 10:07
0

I think this what you want,

$string ="Folder1/Folder2/Folder3/filename1\n";
$string .="Folder1/Folder2/Folder3/filename2\n";
$string .="Folder4/Folder2/Folder3/filename3\n";


$string_array_1 = explode("\n", $string);

$array_need = array();

foreach($string_array_1 as $array_values)
{
        if($array_values)
        {
            $folders =  explode("/", $array_values);
            $array_need[$folders[0]][$folders[1]][$folders[2]][] = $folders[3];
        }
    }

print_r($array_need);
GoSmash
  • 1,096
  • 1
  • 11
  • 38
0

This can be solved recursively in another way by taking the items from the beginning of the array and when the last item is reached just return it.

function make_tree( $arr ){
   if( count($arr) === 1){
      return array_pop( $arr );
   }else{
      $result[ array_shift( $arr )] = make_tree( $arr ) ; 
   }
   return $result;
}

$string  = "Folder1/Folder2/Folder3/filename1\n";
$string .= "Folder1/Folder2/Folder3/filename2\n";
$string .= "Folder4/Folder2/Folder3/filename3\n";

$string = trim( $string );

$files_paths = explode( PHP_EOL, $string);

$result = [];

foreach ($files_paths as $key => $value) {
   $parted = explode( '/', $value );
   $tree = make_tree( $parted );
   $result = array_merge_recursive( $result, $tree );
   
}
var_dump( $result );
Al-Amin
  • 596
  • 3
  • 16