I have an array of strings that are formatted like this:

$strings = array(
   "/user",
   "/robot",
   "/user/1",
   "/user/2",
   "/user/2/test",
   "/robot/1"
);

What I need to do is turn this into an array of the following structure when I print_r() it:

Array
(
  [user] => Array (
    [1] => array(),
    [2] => Array (
      [test] => array()
    )
  [robot] => Array (
      [1] => array()
    )
)

I know I need to explode the original string by delimiter /. However my problem is how do I then build the dynamic array.

Please note that the strings could potentially have an unlimited amount of slashes.

link|improve this question
Think recursively. For instance, you could explode each original element once and pass the exploded array into a function which will navigate down the tree until it reaches the last element of the exploded array, at which point it will insert the element. – Tim Jan 24 at 20:08
2  
FYI, I'm guessing this got downvoted because it is a "gimme teh codez" question. – Phoenix Jan 24 at 20:16
feedback

closed as not a real question by casperOne Jan 25 at 22:13

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. See the FAQ for guidance on how to improve it.

2 Answers

up vote 1 down vote accepted

You can use a reference to progressively build an array as you traverse through the list.

$strings = array(
   "/user",
   "/robot",
   "/user/1",
   "/user/2",
   "/user/2/test",
   "/robot/1"
);

$extracted = array();

foreach( $strings as $string )
{
  $pos =& $extracted;
  foreach( explode('/', ltrim($string, '/')) as $split )
  {
    if( ! isset($pos[$split]) )
    {
      $pos[$split] = array();
    }

    $pos =& $pos[$split];
  }
}

print_r($extracted);

This code might not handle empty elements very well (e.g., /user//4//////test), depending on your requirements.

link|improve this answer
Nice, posted exactly at the same time and the solution is exactly the same... cheers phoenix – Mathieu Dumoulin Jan 24 at 20:10
@MathieuDumoulin Yours has a good explanation, and there are a couple of differences between the two approaches that hopefully will at least give the OP an opportunity to learn something from this little exercise. You get a +1 from me, too (: – Phoenix Jan 24 at 20:17
feedback

The following piece of code should give you what you look for or very near...

$result = array();
foreach($strings as $string){

    $exploded = explode('/', substr($string, 1));
    $path = &$result;

    foreach($exploded as $explodedpart){
        if(!array_key_exists($explodedpart, $path)){
            $path[$explodedpart] = array();
        }
        $path = &$path[$explodedpart];
    }
}

Initialize the array and then loop all strings and exploded them on the / (removing the first one). Then, setup an initial reference to the first level of the results array. Notice the &, it is critical in this algorithm to keep going.

Then, looping each part of the string that you exploded, you check if the part exists as a key inside the current $path which is linked to the current step in results we are at. On each loop, we create the missing key and initialize it to array() and then take that new array and save it as the new $path using a reference...

Good luck with the rest

link|improve this answer
feedback

Not the answer you're looking for? Browse other questions tagged or ask your own question.