SitePoint Sponsor

User Tag List

Results 1 to 2 of 2
  1. #1
    SitePoint Member
    Join Date
    Nov 2007
    Posts
    15
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Nested List with RecursiveArrayIterator

    Using standard recursion I would do something like this
    PHP Code:
    function print_list($data $depth 1) {
        echo 
    str_repeat("\t"$depth 1), "<ul>"PHP_EOL;
        foreach (
    $array as $key => $val) {
            if (
    is_array($val)) {
                echo 
    str_repeat("\t"$depth),"<li>"$keyPHP_EOLprint_list($val$depth 1), "</li>"PHP_EOL;     
            }
            else {
                echo 
    str_repeat("\t"$depth), "<li>",$val,"</li>"PHP_EOL;
            }
        }
        echo 
    str_repeat("\t"$depth 1),"</ul>"PHP_EOL;

    For an array like
    PHP Code:
    $array = array(
        
    "Level 1" => array (
            
    "Level 2" => array(
                
    "Item 1""Item 2"
            
    ),
            
    "Level 2" => array(
                
    "Item 1""Item 2"
            
    )
        )
    ); 
    And this produces a nice XHTML compliant list
    Code HTML4Strict:
    <ul>
            <li>Level 1
            <ul>
                    <li>Level 2
                    <ul>
                            <li>Item 1</li>
                            <li>Item 2</li>
                    </ul>
    				</li>
                    <li>Level 2
                    <ul>
                            <li>Item 1</li>
                            <li>Item 2</li>
                    </ul>
    				</li>
            </ul>
    		</li>
    </ul>
    I would like to do this with the SPL's RecursiveIteratorIterator...
    My failed attempt looks like this:

    PHP Code:
    class RecursiveListIterator extends RecursiveIteratorIterator {
        function 
    beginChildren() {
            echo 
    str_repeat("\t"$this->getDepth() );
            echo 
    "<ul>\n";
            
        }
        
        function 
    endChildren() {
            echo 
    str_repeat("\t"$this->getDepth());
            echo 
    "</ul>\n";
        }
    }

    $it = new RecursiveListIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST ); 
    foreach(
    $it as $key => $item) {
        echo 
    "<li>";
        if (
    $it->getInnerIterator()->hasChildren()) {
                echo 
    $key;
        }
        else {
                echo 
    $item;
        }
        echo 
    "</li>";

    This creates an "</li>" after every item as opposed to my recursive function which recursively prints the child lists before enclosing the "<li>"

    I feel like the solution is there, and I just need to modify one small thing, but I can't find it.

  2. #2
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,397
    Mentioned
    65 Post(s)
    Tagged
    0 Thread(s)
    I've not really done a lot with the recursive iterators, so this may not be the best or ideal approach, but here's something which seems to work as you want it to or at least will provide a little step forward (I hope).

    PHP Code:
    <?php header('Content-Type: text/html; charset=utf-8'); error_reporting(E_ALL E_STRICT);

    $array = array(
        
    "Level 1" => array (
            
    "Level 2.1" => array(
                
    "Item 3.1""Item 3.2"
            
    ),
            
    "Level 2.2" => array(
                
    "Item 3.3""Item 3.4"
            
    ),
            
    "Level 2.3" // => array()
        
    )
    );

    class 
    RecursiveListIterator extends RecursiveIteratorIterator {
        
        public 
    $tab "\t";
        
        public function 
    beginChildren() {
            if (
    count($this->getInnerIterator()) == 0) { return; }
            echo 
    str_repeat($this->tab$this->getDepth()), "<ul>\n";
        }
        
        public function 
    endChildren() {
            if (
    count($this->getInnerIterator()) == 0) { return; }
            echo 
    str_repeat($this->tab$this->getDepth()), "</ul>\n";
            echo 
    str_repeat($this->tab$this->getDepth()), "</li>\n";
        }
        
        public function 
    nextElement() {
            
    // Display leaf node 
            
    if ( ! $this->callHasChildren()) {
                echo 
    str_repeat($this->tab$this->getDepth()+1), '<li>'$this->current(), "</li>\n";
                return;
            }
            
            
    // Display branch with label
            
    echo str_repeat($this->tab$this->getDepth()+1), '<li>'$this->key();
            echo (
    count($this->callGetChildren()) == 0) ? "</li>\n" "\n";
        }
    }

    $it = new RecursiveListIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST); 
    echo 
    "<ul>\n";
    foreach(
    $it as $key => $item); 
    echo 
    "</ul>\n";


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •