Iterator count: примеры (PHP)

Подсчет элементов в итераторах PHP с iterator_count
Раздел: Итераторы
iterator_count(Traversable $iterator): int
Основы функции iterator_count

Функция iterator_count() подсчитывает количество элементов в итераторе. Она принимает итератор в качестве аргумента и возвращает количество оставшихся элементов после его прохода.

Аргументы функции
  • iterator (Traversable) — обязательный аргумент. Итератор, элементы которого нужно подсчитать.
Когда используется

Функция применяется для подсчета элементов в итераторах, генераторах или объектах, реализующих интерфейс Traversable. Это полезно при работе с большими наборами данных, которые нежелательно загружать в память целиком.

Простые примеры использования
Пример с ArrayIterator
$array = [1, 2, 3, 4, 5];
$iterator = new ArrayIterator($array);
echo iterator_count($iterator);
5
Пример с генератором
function numberGenerator($max) {
    for ($i = 1; $i <= $max; $i++) {
        yield $i;
    }
}

$generator = numberGenerator(7);
echo iterator_count($generator);
7
Пример с пустым итератором
$emptyIterator = new EmptyIterator();
echo iterator_count($emptyIterator);
0
Похожие функции в PHP
count() и sizeof()

Функции count() и sizeof() подсчитывают элементы в массивах и объектах, реализующих интерфейс Countable. В отличие от iterator_count(), они не перемещают указатель итератора и работают только с countable-типами.

Цикл foreach

Подсчет через foreach с инкрементацией счетчика позволяет получить тот же результат, но требует больше кода. iterator_count() является более лаконичным вариантом.

Аналоги в других языках

Iterator count в Python

Функция sum() с генераторным выражением или len() для итерируемых объектов:

# Для генератора
gen = (x for x in range(10))
print(sum(1 for _ in gen))
10

Iterator count в Javascript

Нет прямой аналогии, но можно преобразовать итератор в массив:

// Для генератора
function* generate() {
    yield 1; yield 2; yield 3;
}
console.log([...generate()].length);
3

Iterator count в MySQL

Аналогичная задача решается с помощью COUNT() в запросах, но это относится к данным в таблицах, а не к итераторам в памяти.

Типичные ошибки
Передача неитерируемого объекта
$notIterator = 42;
echo iterator_count($notIterator);
TypeError: iterator_count(): Argument #1 must be an instance of Traversable, int given
Использование после итерации
$iterator = new ArrayIterator([1, 2, 3]);
foreach ($iterator as $value) {
    // Пропускаем элементы
}
echo iterator_count($iterator);
0

Функция возвращает 0, так как итератор уже был пройден.

История изменений
PHP 8.0

Тип параметра iterator был изменен с Traversable на Traversable|array для обратной совместимости, но передача массива считается устаревшей.

PHP 8.2

Передача массива в iterator_count() теперь вызывает уведомление об устаревании. Рекомендуется использовать ArrayIterator для массивов.

Расширенные примеры
Подсчет с фильтрацией через FilterIterator
Пример php
class EvenFilter extends FilterIterator {
    public function accept(): bool {
        return $this->current() % 2 === 0;
    }
}

$iterator = new EvenFilter(new ArrayIterator(range(1, 10)));
echo iterator_count($iterator);
5
Подсчет элементов в RecursiveIteratorIterator
Пример php
$array = [1, [2, 3], [4, [5, 6]]];
$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($array),
    RecursiveIteratorIterator::LEAVES_ONLY
);
echo iterator_count($iterator);
6
С ограничением по лимиту через LimitIterator
Пример php
$iterator = new LimitIterator(
    new ArrayIterator(range(1, 100)),
    0,
    25
);
echo iterator_count($iterator);
25
Подсчет уникальных элементов через UniqueIterator
Пример php
class UniqueIterator extends FilterIterator {
    private $seen = [];
    public function accept(): bool {
        $current = $this->current();
        if (in_array($current, $this->seen, true)) {
            return false;
        }
        $this->seen[] = $current;
        return true;
    }
}

$iterator = new UniqueIterator(new ArrayIterator([1, 2, 2, 3, 3, 3]));
echo iterator_count($iterator);
3

PHP iterator_count function comments

En
Iterator count Count the elements in an iterator