Функции на итератора
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) в итератор. Ако входният обект вече е Iterator, той се връща непроменен.
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Now you have an Iterator instead of an array
Този метод е полезен, когато трябва да се уверите, че имате Iterator, независимо от типа на входните данни. Това може да бъде полезно при създаване на функции, които работят с различни типове итерационни данни.