微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 PHP 中装饰迭代器 - 启用跳过

如何解决在 PHP 中装饰迭代器 - 启用跳过

我有一个类,它基本上是 PHP 的 DirectoryIterator 的装饰器。每个文件内容都由类处理,然后由 current() 方法返回。当前,当文件是点文件或无法处理文件时,我从 false 方法返回 current()。但我宁愿跳过点和不可处理的文件,只返回处理过的数据。

附言下面的代码一个简化的例子。我不想预处理构造函数中的所有文件

class Pages implements \Iterator
{
    public function __construct(string $path)
    {
        $this->di = new \DirectoryIterator($path);
    }

    public function rewind() {
        return $this->di->rewind();
    }

    public function current() {
        $file = $this->di->current();
        if($file->isDot()) {
            return false;
        }
        $content = file_get_contents($file->getPathName());
        if($content === 'Cannot be processed!') {
            return false;
        }
        return $content;
    }

    public function key() {
        return $this->di->key();
    }

    public function next() {
        return $this->di->next();
    }

    public function valid() {
        return $this->di->valid();
    }
}

解决方法

我终于找到了这个解决方案,希望有人觉得它有帮助。可以将此模式应用于任何装饰的迭代器,最终得到类似“过滤”迭代器的效果。

class FilteredIterator implements \Iterator
{
    protected $currentProcessed = null;
    protected $key = -1; // Keys are maintained by the decorating class

    public function __construct(Iterator $iterator)
    {
        $this->it = $iterator;
    }

    // Iterator interface START -->

    public function rewind() {
        $this->it->rewind();
        $this->forward();
    }

    public function current() {
        return $this->currentProcessed;
    }

    public function key() {
        return $this->key;
    }

    public function next() {
        $this->it->next();
        $this->forward();
    }

    public function valid() {
        return $this->it->valid();
    }

    // <-- Iterator interface END


    protected function forward() : void
    {
        if(!$this->it->valid()) {
            // Stop when iterator is done
            return;
        }
        // Pseudo code,insert expensive processing function here -->
        $content = $this->it->current();
        if($content === 5) {
        // <-- Pseudo code END
            // Skip 
            $this->next();
            return;
        }
        // Update position
        $this->key++;
        // Cache successfully processed step
        $this->currentProcessed = $content;

    }
}

$arrayObject = new ArrayObject([1,2,3,4,5,6]);

$filteredIterator = new FilteredIterator($arrayObject->getIterator());

foreach ($filteredIterator as $key => $value) {
    echo $key . ' -> ' . $value . "\n";
}

//0 -> 1
//1 -> 2
//2 -> 3
//3 -> 4
//4 -> 6

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。