0

I am trying to create a tree from an array like this:

array('admin/home', 'admin/home/page', 'admin/test', 'team/tree/template', 'site');

Or more visually seen as:

admin/home

admin/home/page

admin/test

team/tree/template

site

However, I also need the last nested string of each array to become bolded to signify that it is a webpage itself.

The final product should look like:

    admin
        home
            page
        test
    team
        tree
            template
    site

I have used a few different solutions from this site but I have not been able to get the right outcome.

Any ideas or examples on where I should start would be greatly appreciated, thanks.

4
  • So the array you're working off is an array of strings like "admin/home"? Commented Jun 3, 2012 at 17:49
  • And what exactly do you want to create, HTML output like the tree you're showing (using unordered lists)? Commented Jun 3, 2012 at 17:51
  • yes html output using precode and yes array strings exactly as those Commented Jun 3, 2012 at 17:51
  • and yea order doesn't really matter Commented Jun 3, 2012 at 17:52

1 Answer 1

1

You are probably looking for something like this:

<?php

$items = array('admin/home', 'admin/home/page', 'admin/test', 'site', 'team/tree/template');
sort($items);

$previous = array();
foreach ($items as $item) {
    $path = explode('/', $item);

    // $i is common nesting level of the previous item
    // e.g. 0 is nothing in common, 1 is one level in common, etc.
    for ($i = 0; $i < min(count($path), count($previous)) && ($path[$i] == $previous[$i]); $i++) { }

    // close <ul> from previous nesting levels:
    // that is, we close the amount of levels that the previous and this one have NOT in common
    for ($k = 0; $k < count($previous)-$i-1; $k++) { echo "</ul>"; }
    // $j is the current nesting level
    // we start at the common nesting level
    for ($j = $i; $j < count($path); $j++) {
        // open <ul> for new nesting levels:
        // i.e., we open a level for every level deeper than the previous level
        if ($j >= count($previous))
            echo "<ul>";
        echo "<li>";
        // make the path bold if the end of the current path is reached
        if (count($path)-1 == $j)
            echo "<b>" . $path[$j] . "</b>";
        else
            echo $path[$j];
        echo "</li>";
    }
    $previous = $path;
}
// close remaining <ul>
for ($k = 0; $k < count($previous); $k++) { echo "</ul>"; }
?>

Note that I order the array to make sure that all nested items come next to each other.

It might have some bugs, but I guess you can work them out yourself. Note that I close the list items before opening a nested <ul>. This is not really how it should; I guess you actually should open the nested <ul> in the final <li> at that level, but you can figure that out yourself.

Update I updated the code to properly close the <ul>'s in some cases.

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

1 Comment

No, this is perfect thanks - actually it might even be fine the way it is

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.