useless-stuff
2/11/2016 - 3:01 PM

PHP - Recursive Iterator

PHP - Recursive Iterator

<?php 
/**
 * Class Skills
 */
class Skills implements RecursiveIterator{
    protected $data;
    protected $position;

    /**
     * Skills constructor.
     * @param array $data
     */
    public function __construct(array $data)
    {
        $this->data = $data;
    }


    /**
     * Return the current element
     * @link http://php.net/manual/en/iterator.current.php
     * @return mixed Can return any type.
     * @since 5.0.0
     */
    public function current()
    {
        
        return $this->data[$this->position];
    }

    /**
     * Move forward to next element
     * @link http://php.net/manual/en/iterator.next.php
     * @return void Any returned value is ignored.
     * @since 5.0.0
     */
    public function next()
    {
        ++$this->position;
    }

    /**
     * Return the key of the current element
     * @link http://php.net/manual/en/iterator.key.php
     * @return mixed scalar on success, or null on failure.
     * @since 5.0.0
     */
    public function key()
    {
        
        return $this->position;
    }

    /**
     * Checks if current position is valid
     * @link http://php.net/manual/en/iterator.valid.php
     * @return boolean The return value will be casted to boolean and then evaluated.
     * Returns true on success or false on failure.
     * @since 5.0.0
     */
    public function valid()
    {
        
        return isset($this->data[$this->position]);
    }

    /**
     * Rewind the Iterator to the first element
     * @link http://php.net/manual/en/iterator.rewind.php
     * @return void Any returned value is ignored.
     * @since 5.0.0
     */
    public function rewind()
    {
        $this->position = 0;
    }

    /**
     * Returns if an iterator can be created for the current entry.
     * @link http://php.net/manual/en/recursiveiterator.haschildren.php
     * @return bool true if the current entry can be iterated over, otherwise returns false.
     * @since 5.1.0
     */
    public function hasChildren()
    {
        
        return is_array($this->data[$this->position]);
    }

    /**
     * Returns an iterator for the current entry.
     * @link http://php.net/manual/en/recursiveiterator.getchildren.php
     * @return RecursiveIterator An iterator for the current entry.
     * @since 5.1.0
     */
    public function getChildren()
    {
        if($this->hasChildren()){
            
            return new self($this->data[$this->position]);
        }
    }
}

/**
 * Class Skill
 */
Class Skill{

}

/**
 * Class CollectionsIterator
 */
class CollectionsIterator
{
    static $result = array();

    public static function iterate(RecursiveIterator $iterator)
    {
        foreach ($iterator as $value) {
            if ($iterator->hasChildren()) {
                self::iterate($iterator->getChildren());

                continue;
            }
           self::$result[] = $value;
        }

        return self::$result;
    }
}


$skills = new Skills(
    array(
        // Languages
        'javascripts',
        'php',
        'ruby',
        // Frameworks
        array(
            'jquery',
            'css',
            'angular',
            'react',
            'symfony',
            'zend framework'
        ),
        // OS
        array(
            'ubuntu',
            'debian',
            'centos',
            // Cloud
            array(
                'amazon ws',
                'google cloud',
                'microsoft azure'
            )
        )
    )
);

print_r(CollectionsIterator::iterate($skills));

// Output
[
    {
        0: "javascripts",
        1: "php",
        2: "ruby",
        3: "jquery",
        4: "css",
        5: "angular",
        6: "react",
        7: "symfony",
        8: "zend framework",
        9: "ubuntu",
        10: "debian",
        11: "centos",
        12: "amazon ws",
        13: "google cloud",
        14: "microsoft azure"
    }
]