You should understand, that generator isn't data structure - it's an instance of Generator
class and, actually, it's special sort of Iterator
. Thus, you can't count its items directly (to be precise - that's because Generator
class implements only Iterator
interface, and not Countable
interface. To be honest, I can't imagine how can it implement that)
To count values with native generator you'll have to iterate through it. But that can not be done in common sense - because in most cases it's you who'll decide how many items will be yielded. Famous xrange()
sample from manual:
function xrange($start, $limit, $step = 1) {
if ($start < $limit) {
if ($step <= 0) {
throw new LogicException('Step must be +ve');
}
for ($i = $start; $i <= $limit; $i += $step) {
yield $i;
}
} else {
if ($step >= 0) {
throw new LogicException('Step must be -ve');
}
for ($i = $start; $i >= $limit; $i += $step) {
yield $i;
}
}
}
-as you can see, it's you who must define borders. And final count will depend from that. Iterating through generator will have sense only with static-borders defined generator (i.e. when count of items is always static - for example, defined inside generator strictly). In any other case you'll get parameter-dependent result. For xrange()
:
function getCount(Generator $functor)
{
$count = 0;
foreach($functor as $value)
{
$count++;
}
return $count;
}
-and usage:
var_dump(getCount(xrange(1, 100, 10)));//10
var_dump(getCount(xrange(1, 100, 1)));//100
-as you can see, "count" will change. Even worse, generator hasn't to be finite. It may yield infinite set of values (and borders are defined in external loop, for example) - and this is one more reason which makes "counting" near senseless.