实际上,这取决于您是哪种情况:
案例 1:在迭代之前我数不过来,我关心的是价值观
// The plain old solution
$count = 0;
foreach($traversable as $value) {
// Do something with $value, then…
++$count;
}
案例 2:在迭代之前我无法计算但我不关心值
// let's iterator_count() do it for me
$count = iterator_count($traversable);
案例 3:我可以在迭代之前计算,但我不关心值
我尽量不使用生成器。
例如(使用 SQL 后端):
SELECT count(1) FROM mytable; // then return result
优于
SELECT * FROM mytable; // then counting results
其他示例(使用 Alma Do 的 xrange):
// More efficient than counting by iterating
function count_xrange($start, $limit, $step = 1) {
if (0 === $step) throw new LogicException("Step can't be 0");
return (int)(abs($limit-$start) / $step) + 1;
}
案例 4:我可以在迭代之前计算,我关心值
我可以使用生成器和计数函数
$args = [0,17,2];
$count = count_xrange(...$args);
$traversable = xrange(...$args);
案例 5:案例 4,我想要一个对象
我可以“装饰”一个迭代器来制作一个可数迭代器
function buildCountableIterator(...$args) {
$count = count_xrange(...$args);
$traversable = xrange(...$args);
return new class($count, $traversable) extends \IteratorIterator implements \Countable {
private $count;
public function __construct($count, $traversable) {
parent::__construct($traversable);
$this->count = $count;
}
public function count() {
return $this->count;
}
}
}
$countableIterator = buildCountableIterator(1, 24, 3);
// I can do this because $countableIterator is countable
$count = count($countableIterator);
// And I can do that because $countableIterator is also an Iterator
foreach($countableIterator as $item) {
// do something
}
来源: