在迭代器模式中实现 `continue` 关键字

Implementation of `continue` keyword inside iterator pattern

我发现 continue 功能只能通过递归在迭代器模式中实现。 问题当然是循环遍历数百万个应该继续的无效元素应该非常慢或者堆栈溢出。

如何在迭代器模式中不使用递归来实现 continue 关键字?

PHP 递归代码:

class TableIterator implements \Iterator
{
    private $row;
    private $fileLines;

    public function __construct()
    {
        $this->fileLines = [
            "1, 2, 3, 4, 5, 6, 7, 8",
            "my condition, 9, 10, 11, 12, 13, 14, 15",
            "my condition, 16, 17, 18, 19, 20, 21, 22, 23",
            "24, 25, 26, 27, 28, 29, 30, 31",
            "32, 33, 34, 35, 36, 37, my condition 2, 38",
            "39, 40, 41, 42, 43, 44, 45, 46"
        ];
    }

    public function rewind(): void
    {
        reset($this->fileLines);
    }

    public function current(): array
    {
        return $this->row;
    }

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

    public function next(): void
    {
        next($this->fileLines);
    }

    public function valid(): bool
    {
        $this->row = explode(", ", current($this->fileLines));

        if($this->row[0] === 'my condition')
            $this->continue(); // here is the recursion problem
        
        if($this->row[6] === 'my condition 2')
            return false;

        return true;
    }
    
    private function continue()
    {
        $this->next();
        $this->valid();
    }
}

foreach(new TableIterator() as $key => $value)
    print_r($value);

如果 PHP 有解决方案或破解方法,我会很高兴。 谢谢

我找到了一些解决方法,但它仍然不是理想的解决方案!

问题可能是是否有任何解决方案?

if($value === null) continue; 继续迭代。 评论它以获得空值并且仍然能够获得密钥。问题可能是空值是预期值!

class TableIterator implements \Iterator
{
    private $row;
    private $fileLines;
    private $continue;

    public function __construct()
    {
        $this->fileLines = [
            "1, 2, 3, 4, 5, 6, 7, 8",
            "my condition, 9, 10, 11, 12, 13, 14, 15",
            "my condition, 16, 17, 18, 19, 20, 21, 22, 23",
            "24, 25, 26, 27, 28, 29, 30, 31",
            "32, 33, 34, 35, 36, 37, my condition 2, 38",
            "39, 40, 41, 42, 43, 44, 45, 46"
        ];
    }

    public function rewind(): void
    {
        reset($this->fileLines);
    }

    public function current(): ?array
    {
        if($this->continue)
        {
            $this->continue = false;
            return null;
        }
        
        return $this->row;
    }

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

    public function next(): void
    {
        next($this->fileLines);
    }

    public function valid(): bool
    {
        $this->row = explode(", ", current($this->fileLines));

        if($this->row[0] === 'my condition')
            $this->continue = true;
        
        if($this->row[6] === 'my condition 2')
            return false;

        return true;
    }
}

foreach(new TableIterator() as $key => $value)
{
    if($value === null) continue;
    var_dump($value);
}

这就是解决方案!

2021年我就懒得解释了。 如果你好奇,请爬取整个算法。

class TableIterator implements \Iterator
{
    private $row;
    private $fileLines;

    public function __construct()
    {
        $this->fileLines = [
            "my condition, 16, 17, 18, 19, 20, 21, 22, 23",
            "my condition, 16, 17, 18, 19, 20, 21, 22, 23",
            "my condition, 16, 17, 18, 19, 20, 21, 22, 23",
            "1, 2, 3, 4, 5, 6, 7, 8",
            "my condition, 9, 10, 11, 12, 13, 14, 15",
            "my condition, 16, 17, 18, 19, 20, 21, 22, 23",
            "24, 25, 26, 27, 28, 29, 30, 31",
            "32, 33, 34, 35, 36, 37, my condition 2, 38",
            "39, 40, 41, 42, 43, 44, 45, 46"
        ];
    }

    public function rewind(): void
    {
        reset($this->fileLines);
        
        while($this->continue())
        {
            next($this->fileLines);
        }
    }

    public function current(): array
    {
        return $this->row;
    }

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

    public function next(): void
    {
        do {
            next($this->fileLines);
        }
        while($this->continue());
    }

    public function valid(): bool
    {
        if($this->row[6] === 'my condition 2')
            return false;

        return true;
    }
    
    private function continue()
    {
        $this->row = explode(", ", current($this->fileLines));
        
        return $this->row[0] === 'my condition' ? true : false;
    }
}

foreach(new TableIterator() as $key => $value)
{
    var_dump($value);
}