Функции итератора
Nette\Utils\Iterables это статический класс с функциями для работы с итераторами. Его аналог для массивов – Nette\Utils\Arrays.
Установка:
composer require nette/utils
Во всех примерах предполагается, что создан следующий псевдоним:
use Nette\Utils\Iterables;
contains (iterable $iterable, $value): bool
Поиск заданного значения в итераторе. Использует строгое сравнение
(===
) для проверки совпадения. Возвращает true
, если значение
найдено, иначе false
.
Iterables::contains(new ArrayIterator([1, 2, 3]), 1); // true
Iterables::contains(new ArrayIterator([1, 2, 3]), '1'); // false
Этот метод полезен, когда нужно быстро определить, присутствует ли конкретное значение в итераторе, не перебирая вручную все элементы.
containsKey (iterable $iterable, $key): bool
Поиск заданного ключа в итераторе. Использует строгое сравнение
(===
) для проверки совпадения. Возвращает true
, если ключ
найден, иначе false
.
Iterables::containsKey(new ArrayIterator([1, 2, 3]), 0); // true
Iterables::containsKey(new ArrayIterator([1, 2, 3]), 4); // false
every (iterable $iterable, callable $predicate): bool
Проверяет, все ли элементы итератора удовлетворяют условию,
определенному в $predicate
. Функция $predicate
имеет сигнатуру
function ($value, $key, iterable $iterable): bool
и должна возвращать true
для
каждого элемента, чтобы метод every()
вернул true
.
$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isBelowThreshold = fn($value) => $value < 40;
$res = Iterables::every($iterator, $isBelowThreshold); // true
Этот метод полезен для проверки того, что все элементы коллекции удовлетворяют определенному условию, например, все ли числа меньше определенного значения.
filter (iterable $iterable, callable $predicate): Generator
Создает новый итератор, содержащий только те элементы из исходного
итератора, которые удовлетворяют условию, определенному в
$predicate
. Функция $predicate
имеет сигнатуру
function ($value, $key, iterable $iterable): bool
и должна возвращать true
для
элементов, которые должны быть сохранены.
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::filter($iterator, fn($v) => $v < 3);
// 1, 2
Метод использует генератор, то есть фильтрация происходит инкрементально во время итерации. Это экономит память и позволяет работать с очень большими коллекциями. Если вы не выполняете итерацию по всем элементам результирующего итератора, вы экономите вычислительные усилия, поскольку не все элементы исходного итератора обрабатываются.
first (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Возвращает первый элемент итератора. Если указано $predicate
,
возвращается первый элемент, удовлетворяющий заданному условию.
Функция $predicate
имеет сигнатуру
function ($value, $key, iterable $iterable): bool
. Если не найдено ни одного
удовлетворяющего элемента, вызывается функция $else
(если она
предоставлена) и возвращается ее результат. Если $else
не
предоставлена, возвращается null
.
Iterables::first(new ArrayIterator([1, 2, 3])); // 1
Iterables::first(new ArrayIterator([1, 2, 3]), fn($v) => $v > 2); // 3
Iterables::first(new ArrayIterator([])); // null
Iterables::first(new ArrayIterator([]), else: fn() => false); // false
Этот метод полезен, когда нужно быстро получить первый элемент коллекции или первый элемент, удовлетворяющий определенному условию, без ручного итерационного просмотра всей коллекции.
firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Возвращает ключ первого элемента итератора. Если указано
$predicate
, возвращается ключ первого элемента, удовлетворяющего
заданному условию. Функция $predicate
имеет сигнатуру
function ($value, $key, iterable $iterable): bool
. Если ни один элемент не найден,
вызывается функция $else
(если она предоставлена) и возвращается
ее результат. Если $else
не предоставлена, возвращается
null
.
Iterables::firstKey(new ArrayIterator([1, 2, 3])); // 0
Iterables::firstKey(new ArrayIterator([1, 2, 3]), fn($v) => $v > 2); // 2
Iterables::firstKey(new ArrayIterator(['a' => 1, 'b' => 2])); // 'a'
Iterables::firstKey(new ArrayIterator([])); // null
map (iterable $iterable, callable $transformer): Generator
Создает новый итератор путем применения функции $transformer
к
каждому элементу исходного итератора. Функция $transformer
имеет
сигнатуру function ($value, $key, iterable $iterable): mixed
, а ее возвращаемое
значение используется в качестве нового значения элемента.
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::map($iterator, fn($v) => $v * 2);
// 2, 4, 6
Метод использует генератор, то есть преобразование происходит инкрементально во время итерации. Это экономит память и позволяет работать с очень большими коллекциями. Если вы не выполняете итерацию по всем элементам результирующего итератора, вы экономите вычислительные усилия, поскольку не все элементы исходного итератора обрабатываются.
mapWithKeys (iterable $iterable, callable $transformer): Generator
Создает новый итератор путем преобразования значений и ключей
исходного итератора. Функция $transformer
имеет сигнатуру
function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}
. Если $transformer
возвращает null
, элемент пропускается. Для сохраненных элементов
первый элемент возвращаемого массива используется в качестве нового
ключа, а второй элемент – в качестве нового значения.
$iterator = new ArrayIterator(['a' => 1, 'b' => 2]);
$iterator = Iterables::mapWithKeys($iterator, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Как и map()
, этот метод использует генератор для инкрементной
обработки и эффективности использования памяти. Это позволяет
работать с большими коллекциями и экономить вычислительные усилия,
обрабатывая только часть результата.
memoize (iterable $iterable): IteratorAggregate
Создает обертку вокруг итератора, которая кэширует его ключи и значения во время итерации. Это позволяет повторять итерации над данными без необходимости повторной обработки исходного источника данных.
$iterator = /* data that cannot be iterated multiple times */
$memoized = Iterables::memoize($iterator);
// Now you can iterate $memoized multiple times without data loss
Этот метод полезен в ситуациях, когда вам нужно несколько раз просмотреть один и тот же набор данных, но исходный итератор не поддерживает повторную итерацию или повторная итерация будет дорогостоящей (например, при чтении данных из базы данных или файла).
some (iterable $iterable, callable $predicate): bool
Проверяет, удовлетворяет ли хотя бы один элемент итератора условию,
определенному в $predicate
. Функция $predicate
имеет сигнатуру
function ($value, $key, iterable $iterable): bool
и должна вернуть true
хотя бы
для одного элемента, чтобы метод some()
вернул true
.
$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isEven = fn($value) => $value % 2 === 0;
$res = Iterables::some($iterator, $isEven); // true
Этот метод полезен для быстрой проверки того, есть ли в коллекции хотя бы один элемент, удовлетворяющий определенному условию, например, содержит ли коллекция хотя бы одно четное число.
Смотрите every().
toIterator (iterable $iterable): Iterator
Преобразует любой итерируемый объект (массив, Traversable) в итератор. Если входной объект уже является итератором, он возвращается без изменений.
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Now you have an Iterator instead of an array
Этот метод полезен, когда нужно убедиться, что у вас есть итератор, независимо от типа входных данных. Это может быть полезно при создании функций, работающих с разными типами итерируемых данных.