Iterator to array: примеры (PHP)
iterator_to_array(Traversable $iterator, bool $preserve_keys = true): arrayФункция iterator_to_array преобразует объект, реализующий интерфейс Traversable (например, итератор или генератор), в обычный массив. Это полезно, когда требуется работать с данными как с массивом, но источник данных предоставляет итератор.
Использование функции актуально в ситуациях, когда операции требуют индексированный или ассоциативный массив, а не объект-итератор. Например, для многократного прохода по данным, случайного доступа к элементам или использования функций для работы с массивами.
- iterator (обязательный): Объект, реализующий интерфейс
Traversable. - preserve_keys (необязательный): Булевый параметр. При значении
trueключи итератора сохраняются. Приfalseили отсутствии параметра - результат будет массивом с числовыми индексами, начиная с нуля. - use_keys (необязательный): Доступен с PHP 8.2. Булевый параметр. При значении
trueключи, возвращаемые итератором, используются в результирующем массиве. Еслиfalse, ключи игнорируются и массив индексируется численно.
Стандартный вызов без второго параметра:
$iterator = new ArrayIterator(['a', 'b', 'c']);
$array = iterator_to_array($iterator);
print_r($array);Array
(
[0] => a
[1] => b
[2] => c
)Использование параметра preserve_keys:
$iterator = new ArrayIterator(['first' => 'a', 'second' => 'b']);
$array = iterator_to_array($iterator, true);
print_r($array);Array
(
[first] => a
[second] => b
)Использование параметра use_keys:
// PHP 8.2 и выше
$iterator = new ArrayIterator([10 => 'x', 20 => 'y']);
$array = iterator_to_array($iterator, use_keys: false);
print_r($array);Array
(
[0] => x
[1] => y
)Генератор также является объектом типа Traversable:
function simpleGenerator() {
yield 'apple';
yield 'banana';
}
$array = iterator_to_array(simpleGenerator());
print_r($array);Array
(
[0] => apple
[1] => banana
)Прямое использование foreach для итерации без создания массива. Подходит для последовательной обработки элементов без необходимости хранения всего набора данных в памяти одновременно.
Функция iterator_count подсчитывает количество элементов в итераторе. Используется, когда нужен только размер данных, а не сами значения.
Для объектов, не реализующих Traversable, но когда необходимо получить свойства, может применяться get_object_vars. Функция iterator_to_array работает только с итерируемыми объектами.
Создание массива вручную через foreach дает больше контроля над процессом, например, фильтрацию или преобразование данных на лету.
Критерии выбора: iterator_to_array выбирают для быстрого преобразования итератора в массив. foreach предпочтительнее для обработки больших данных без загрузки в память. iterator_count используют для получения количества элементов.
Iterator to array в Python
В Python итераторы можно преобразовать в список с помощью функции list() или в словарь с помощью dict().
# Пример с генератором
def simple_gen():
yield 'a'
yield 'b'
result_list = list(simple_gen())
print(result_list) # ['a', 'b']Iterator to array в Javascript
В современных версиях JavaScript итерируемые объекты можно преобразовать в массив с помощью Array.from() или оператора расширения ....
// Пример с генератором
function* simpleGen() {
yield 'x';
yield 'y';
}
const arr = Array.from(simpleGen());
console.log(arr); // ['x', 'y']
// Или с использованием оператора расширения
const arr2 = [...simpleGen()];
console.log(arr2); // ['x', 'y']Iterator to array в MySQL
Прямого аналога нет. Обычно курсоры (аналоги итераторов) обрабатываются последовательно в процедурах, а результаты SELECT сразу представляются как результирующий набор, который можно воспринимать как таблицу данных.
В PHP функция явно принимает флаги для управления ключами. В Python и JavaScript преобразование чаще зависит от типа целевой коллекции (список, словарь, массив). Универсальность PHP функции заключается в работе с любым объектом типа Traversable.
Попытка использовать функцию с объектом, который не реализует интерфейс Traversable.
class NotIterable {}
$obj = new NotIterable();
// Вызовет TypeError
try {
$array = iterator_to_array($obj);
} catch (TypeError $e) {
echo $e->getMessage();
}iterator_to_array(): Argument #1 ($iterator) must be of type Traversable, NotIterable givenПреобразование бесконечного генератора приводит к исчерпанию памяти.
function infiniteGenerator() {
while (true) {
yield rand();
}
}
// Приведет к фатальной ошибке из-за нехватки памяти
// $array = iterator_to_array(infiniteGenerator());Если preserve_keys=true и итератор возвращает дублирующиеся ключи, предыдущие значения перезаписываются.
$iterator = new ArrayIterator(['a', 'b', 'a' => 'c', 'a' => 'd']);
$array = iterator_to_array($iterator, true);
print_r($array);Array
(
[0] => a
[1] => b
[a] => d
)Ключ 'a' встретился дважды, в массиве осталось последнее значение 'd'.
Добавлен третий параметр use_keys. Это позволяет явно указать, следует ли использовать ключи из итератора. Поведение при use_keys: true аналогично preserve_keys: true в предыдущих версиях. Параметр preserve_keys остается для обратной совместимости, но его использование с use_keys может привести к неочевидным результатам.
Изменена сигнатура функции для включения типизированных параметров. Ошибки типа теперь вызывают исключение TypeError вместо предупреждений.
До PHP 5.5 функция не могла корректно обрабатывать генераторы, так как они были добавлены именно в этой версии.
Использование с итераторами, которые фильтруют данные.
class NumberFilter extends FilterIterator {
public function accept(): bool {
return is_numeric($this->current()) && $this->current() % 2 === 0;
}
}
$arrayIterator = new ArrayIterator([1, 2, 3, 4, 'apple', 6]);
$filterIterator = new NumberFilter($arrayIterator);
$result = iterator_to_array($filterIterator, false);
print_r($result);Array
(
[0] => 2
[1] => 4
[2] => 6
)Получение части данных из итератора.
$iterator = new ArrayIterator(range('A', 'Z'));
$limitIterator = new LimitIterator($iterator, 5, 3); // Смещение 5, лимит 3
$array = iterator_to_array($limitIterator);
print_r($array);Array
(
[0] => F
[1] => G
[2] => H
)Итератор может содержать объекты в качестве элементов.
class Item {
public function __construct(public string $name) {}
}
$items = [new Item('Chair'), new Item('Table')];
$iterator = new ArrayIterator($items);
$array = iterator_to_array($iterator);
// Массив содержит те же объекты
print_r($array[0]);Item Object
(
[name] => Chair
)Преобразование многоуровневых структур в плоский массив.
$multiArray = new RecursiveArrayIterator([1, [2, 3], [4, [5]]]);
$flatIterator = new RecursiveIteratorIterator($multiArray);
$flatArray = iterator_to_array($flatIterator, false);
print_r($flatArray);Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)Генераторы могут возвращать пары ключ-значение.
function keyValueGenerator() {
yield 'id' => 100;
yield 'name' => 'John';
yield 'active' => true;
}
$array = iterator_to_array(keyValueGenerator(), true);
print_r($array);Array
(
[id] => 100
[name] => John
[active] => 1
)