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 ?

4
  • Well, if you have a string, and you ultimately want a string, why would you want an array? Commented Apr 12, 2012 at 12:32
  • possible duplicate of String with array structure to Array Commented Apr 12, 2012 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. Commented Apr 12, 2012 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: 3v4l.org/UGK0l Commented Apr 6, 2018 at 5:12

3 Answers 3

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.

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

2 Comments

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.
Added code to process your multi-line strings. Now it outputs the exact same array as you need.
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);

1 Comment

It is great, but not dynamic. What if the number of subfolders change Folder5/Folder2/Folder3/Folder4/filename4
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 );

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.