问题描述
我发现 continue
功能只能通过递归在迭代器模式中实现。
问题当然是循环遍历数百万个应该继续的无效元素应该是超慢的或者永远堆栈溢出。
如何在迭代器模式中不使用递归实现continue
关键字?
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",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);
解决方法
我想出了一些解决方法,但它仍然不是理想的解决方案!
问题可能是,是否有任何解决方案?
if($value === null) continue;
继续迭代。
注释它以获得空值并且仍然能够获得键。问题可能出在 null 是预期值时!
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",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,"1,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);
}