-1

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.

2
  • 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. Commented Jan 24, 2012 at 20:08
  • 2
    FYI, I'm guessing this got downvoted because it is a "gimme teh codez" question. Commented Jan 24, 2012 at 20:16

2 Answers 2

2

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.

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

2 Comments

Nice, posted exactly at the same time and the solution is exactly the same... cheers phoenix
@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 (:
1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.