1

I'm quite new to programming and I've been trying to get something, that seemed rather simple, done but it's taking me way too long and I do not have the feeling that I'm getting anywhere close...

I'm trying to format an array that looks like this:

Array (
    [1] = "index.php"
    [2] = "page.php"
    [3] = "sub/subpage.php"
    [4] = "sub/subpage2.php"
    [5] = "sub/subsub/subsubpage.php"
    [6] = "sub/subsub/subsubpage2.php"
    [7] = "sub2/sub2page.php"
)

Into an array that looks like this:

Array (
    [/] => Array (
              [0] => "index.php"
              [1] => "page.php"
          )
    [/sub] => Array (
              [0] => "subpage.php"
              [1] => "subpage2.php"
              [/subsub] => Array (
                  [0] => "subsubpage.php"
                  [1] => "subsubpage2.php"
              )
          )
    [/sub2] => Array (
              [0] => "sub2page.php"
          )
)

I'm hoping this example shows what I'm trying to do... Which is basically reformatting my original (simple) array into an array that I can use to create some kind of navigation in HTML (using nested ul's)

Thanks in advance!

EDIT:

I've tried this to create the multidimensional array...

 $parts = explode('/', trim($page["parent"], "/"));
 while ( !empty($parts) ) {
     $pageList[array_pop($parts)] = $page["filename"];
 }

 // $page = array("filename" => "example.php", "parent" => "sub/sub/")
3
  • I'm having problems coming up with a function that does this... I added something I tried to the OP. Commented Feb 11, 2013 at 20:08
  • Can you add what the $page object contains? Commented Feb 11, 2013 at 20:11
  • I'm sorry, I added that. Commented Feb 11, 2013 at 20:14

3 Answers 3

1

I've prepared an example how to achieve this. The array $from

$from = array (
    "index.php",
    "page.php",
    "sub/subpage2.php",
    "sub/subsub/subpage2.php",
    "sub2/sub2page.php",
);

will be converted to $to:

$to = array();
foreach($from as $element) {
    $path = explode('/', $element);
    if(count($path) === 1) {
        array_unshift($path, '/');
    }
    $_to = &$to;
    for($i=0; $i<count($path) -1; $i++) {
        if(!array_key_exists($path[$i], $_to)) {
            $_to[$path[$i]]= array();
        }
        $_to = &$_to[$path[$i]];
    }
    $_to []= $path[count($path) -1];
}
var_dump($to);

.. what gives you the following array:

array(3) {
  '/' =>
  array(2) {
    [0] =>
    string(9) "index.php"
    [1] =>
    string(8) "page.php"
  }
  'sub' =>
  array(2) {
    [0] =>
    string(11) "subpage.php"
    'subsub' =>
    array(1) {
      [0] =>
      string(12) "subpage2.php"
    }
  }
  'sub2' =>
  array(1) {
    [0] =>
    string(12) "sub2page.php"
  }
}
Sign up to request clarification or add additional context in comments.

8 Comments

A little less close than Philip. There are 2 problems with this approach. 1) I need index.php and page.php in one array (with key /) and 2) I need /subsub inside /sub...
@CasCornelissen If you need subsub in sub, then you'll have just to change $from. My code works with that
Oh wow, it works! Thanks so much... I'm going to try to understand it now, haha.
Yes. I'm looping over directories in path ( < count($path) -1) If a directory does not exist in $to I create it. The last element is always the filename and will get added to the corresponding directory entry.
Note one last thing. If you don't expect NULL values (unlikely) you can replace array_key_exists() by isset() which is faster.
|
1

You mean something like this - thats just an simple parser

$test = array(
    "index.php",
    "page.php",
    "sub/subpage.php",
    "sub/subpage2.php",
    "sub/subsub/subsubpage.php",
    "sub/subsub/subsubpage2.php",
    "sub2/sub2page.php"
);


function buildPathArray($array)
{
    $t = array();

    foreach ($array as $file) {
        $path = "/";
        $name = $file;

        if (preg_match('~^(.*)/([^/]+)$~', $file, $m)) {
            $path = $m[1];
            $name = $m[2];
        }

        $p = &arrayPath($t, $path);

        $p[] = $name;
    }

    return $t;
}

function &arrayPath(&$array, $path = false)
{
    if ($path == false) {
        return $array;
    }
    else
    {
        if (strpos($path, '/') === false) {
            if (!isset($array[$path])) {
                $array[$path] = array();
            }

            return $array[$path];
        }
        else
        {
            preg_match('~([^/]*)/(.*)~', $path, $m);
            if (!isset($array[$m[1]])) {
                $array[$m[1]] = array();
            }

            return arrayPath($array[$m[1]], $m[2]);
        }
    }
}

5 Comments

This is getting closer but I already got this once (forgot how to though). I need /subsub inside /sub...
But this information isn't available in your array structure... you have to replace subsub/subsubpage.php with sub/subsub/subsubpage.php or this isn't possible
Oh god, I made a mistake. It has to be like that... I'll fix my OP, could you then look at it again?
Nevermind, hek2mgl's approach worked. Thanks for your time though!
Postet an solution as well - especially because of arrayPath which could be usefull for other persons too
0

If you want to use an array like that you key values need to be in quotes as well. For consider:

$array = array(
    '/' => array('index.php', 'page.php'),
    '/sub' => array('blah', 'blah', 'blah'),
    '/sub2' => array('foo', 'bar', 'foobar')
);

How you correctly set key values using the array keyword is without bracket notation. This is incorrect

$array = array(
    [key] => 'value'
);

However, if you want to add something to an array...

$array = array();
$array['foo'] = 'bar'; // named key value
$array[] = 'blah'; // automatic numeric key value
$array[] = array('foo', 'bar'); // md array (array inside an array)

Hopefully this helps you out some!

1 Comment

I know how to define arrays, I was using the notation in the example since I want to look them that way when using print_r

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.