Is iterable: примеры (PHP)
is_iterable(mixed $value): boolФункция is_iterable() проверяет, является ли переданное значение итерируемым, то есть таким, по которому можно пройтись с помощью конструкции foreach. Она была введена в PHP 7.1.
Функция используется в ситуациях, когда код должен работать с данными, которые могут быть представлены в разных форматах: массивами, объектами, реализующими интерфейс Traversable, или генераторами. Это упрощает проверку перед началом цикла.
Функция принимает один обязательный аргумент:mixed $value — проверяемое значение. Может быть любого типа.
Функция возвращает true, если $value является массивом, объектом, реализующим Traversable, или генератором. В противном случае возвращает false.
$arr = [1, 2, 3];
var_dump(is_iterable($arr));bool(true)
$obj = new ArrayIterator(['a', 'b', 'c']);
var_dump(is_iterable($obj));bool(true)
function gen() { yield 1; }
$generator = gen();
var_dump(is_iterable($generator));bool(true)
var_dump(is_iterable(123));
var_dump(is_iterable('строка'));
var_dump(is_iterable(null));bool(false) bool(false) bool(false)
$std = new stdClass();
var_dump(is_iterable($std));bool(false)
В PHP существуют другие функции для проверки типа данных, которые могут быть использованы в похожих контекстах.
Проверяет, является ли переменная массивом. is_iterable() шире, так как принимает и объекты с Traversable.
Проверка с помощью оператора instanceof позволяет определить, реализует ли объект интерфейс Traversable (который реализуют Iterator и IteratorAggregate). Однако этот способ не сработает для массивов и генераторов.
$obj = new ArrayIterator([]);
$check = ($obj instanceof Traversable); // true
$check2 = ([] instanceof Traversable); // Ошибкаis_iterable() предпочтительнее, когда нужна универсальная проверка для передачи в foreach. is_array() используется, когда важна именно массивная структура. instanceof Traversable применяется для строгой проверки объектов-итераторов.
Объекты класса stdClass по умолчанию не реализуют Traversable.
$data = (object) ['a' => 1];
if (is_iterable($data)) {
foreach ($data as $v) { /* этот блок не выполнится */ }
}
echo 'Объект stdClass не прошел проверку is_iterable.';Объект stdClass не прошел проверку is_iterable.
Функция is_countable() проверяет, что по значению можно пройти функцией count(). Не все итерируемые значения являются countable (например, генераторы).
function gen() { yield 1; }
$g = gen();
var_dump(is_iterable($g)); // true
var_dump(is_countable($g)); // false
bool(true) bool(false)
Функция is_iterable() была добавлена в PHP 7.1. В PHP 8.0 и позднее ее поведение не изменялось. Добавление функции было логичным шагом для замены распространенной, но неудобной проверки is_array($var) || $var instanceof Traversable.
function processIterable(iterable $items) {
foreach ($items as $item) {
echo $item . "\n";
}
}
// Проверка перед вызовом функции, требующей iterable
$potentialData = getDataFromSource(); // Может вернуть разное
if (is_iterable($potentialData)) {
processIterable($potentialData);
} else {
echo 'Данные для обработки не итерируемы.';
}
// Пример возврата из getDataFromSource
function getDataFromSource() {
// Может вернуть массив...
// return ['A', 'B'];
// ... или объект-итератор...
// return new ArrayIterator(['X', 'Y']);
// ... или что-то еще.
return 'просто строка';
}Данные для обработки не итерируемы.
В PHP 7.1+ можно использовать iterable как тип параметра или возвращаемого значения. Функция is_iterable() полезна для внутренних проверок, когда тип не строгий.
function handleData(iterable $data): void {
// Здесь $data гарантированно итерируема.
var_dump('Приняты итерируемые данные', is_iterable($data));
}
handleData([1,2]); // Работает
// handleData(123); // Вызовет TypeErrorstring(47) "Приняты итерируемые данные" bool(true)
class MyCollection implements IteratorAggregate {
private $items = [];
public function add($item) { $this->items[] = $item; }
public function getIterator(): Traversable {
return new ArrayIterator($this->items);
}
}
$collection = new MyCollection();
$collection->add('Первый');
$collection->add('Второй');
var_dump(is_iterable($collection));
foreach ($collection as $item) {
echo $item . " ";
}bool(true) Первый Второй
$generator = (function() { yield from []; })();
// Старый способ
$oldCheck = (is_array($generator) || $generator instanceof Traversable);
var_dump($oldCheck);
// Новый способ
$newCheck = is_iterable($generator);
var_dump($newCheck);bool(true) bool(true)
Хотя результат одинаков, is_iterable() короче и понятнее, а также корректно работает с генераторами, которые являются объектами, реализующими Traversable.
Is iterable в Python
В Python используется функция iter() в сочетании с обработкой исключения TypeError или абстрактный базовый класс collections.abc.Iterable.
from collections.abc import Iterable
print(isinstance([1,2], Iterable)) # True
print(isinstance(123, Iterable)) # FalseIs iterable в Javascript
В JavaScript проверка на итерируемость часто заключается в проверке наличия метода [Symbol.iterator]. Универсальной встроенной функции для этого нет.
function isIterable(obj) {
return obj != null && typeof obj[Symbol.iterator] === 'function';
}
console.log(isIterable([1,2])); // true
console.log(isIterable({})); // falseIs iterable в MySQL
Прямого аналога в SQL нет, так как это язык запросов, а не императивного программирования. Концепция итерирования применяется на уровне обработки результирующих наборов в коде приложения.