Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|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 '12 at 20:08
2  
FYI, I'm guessing this got downvoted because it is a "gimme teh codez" question. –  todofixthis Jan 24 '12 at 20:16
add comment

closed as not a real question by casperOne Jan 25 '12 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. For help clarifying this question so that it can be reopened, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

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.

share|improve this answer
 
Nice, posted exactly at the same time and the solution is exactly the same... cheers phoenix –  Mathieu Dumoulin Jan 24 '12 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 (: –  todofixthis Jan 24 '12 at 20:17
add comment

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

share|improve this answer
add comment

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