Funkcje iteratora

Nette\Utils\Iterables to statyczna klasa z funkcjami do pracy z iteratorami. Jej odpowiednikiem dla tablic jest Nette\Utils\Arrays.

Instalacja:

composer require nette/utils

Wszystkie przykłady zakładają utworzenie następującego aliasu:

use Nette\Utils\Iterables;

contains (iterable $iterable, $value)bool

Wyszukuje daną wartość w iteratorze. Używa ścisłego porównania (===), aby sprawdzić dopasowanie. Zwraca true jeśli wartość zostanie znaleziona, w przeciwnym razie false.

Iterables::contains(new ArrayIterator([1, 2, 3]), 1);    // true
Iterables::contains(new ArrayIterator([1, 2, 3]), '1');  // false

Ta metoda jest przydatna, gdy trzeba szybko określić, czy określona wartość jest obecna w iteratorze bez ręcznego iterowania przez wszystkie elementy.

containsKey (iterable $iterable, $key)bool

Wyszukuje dany klucz w iteratorze. Używa ścisłego porównania (===) do sprawdzenia dopasowania. Zwraca true jeśli klucz został znaleziony, w przeciwnym razie 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

Sprawdza, czy wszystkie elementy iteratora spełniają warunek zdefiniowany w $predicate. Funkcja $predicate ma sygnaturę function ($value, $key, iterable $iterable): bool i musi zwrócić true dla każdego elementu, aby metoda every() zwróciła true.

$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isBelowThreshold = fn($value) => $value < 40;
$res = Iterables::every($iterator, $isBelowThreshold); // true

Metoda ta jest przydatna do sprawdzania, czy wszystkie elementy w kolekcji spełniają określony warunek, np. czy wszystkie liczby są poniżej określonej wartości.

filter (iterable $iterable, callable $predicate): Generator

Tworzy nowy iterator, który zawiera tylko te elementy z oryginalnego iteratora, które spełniają warunek zdefiniowany w $predicate. Funkcja $predicate ma sygnaturę function ($value, $key, iterable $iterable): bool i musi zwracać true dla elementów, które powinny zostać zachowane.

$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::filter($iterator, fn($v) => $v < 3);
// 1, 2

Metoda wykorzystuje generator, co oznacza, że filtrowanie odbywa się przyrostowo podczas iteracji. Jest to wydajne pod względem pamięci i pozwala na obsługę bardzo dużych kolekcji. Jeśli nie iterujesz przez wszystkie elementy wynikowego iteratora, oszczędzasz wysiłek obliczeniowy, ponieważ nie wszystkie elementy oryginalnego iteratora są przetwarzane.

first (iterable $iterable, ?callable $predicate=null, ?callable $else=null)mixed

Zwraca pierwszy element iteratora. Jeśli podano $predicate, zwraca pierwszy element, który spełnia podany warunek. Funkcja $predicate ma sygnaturę function ($value, $key, iterable $iterable): bool. Jeśli nie zostanie znaleziony żaden pasujący element, wywoływana jest funkcja $else (jeśli została podana) i zwracany jest jej wynik. Jeśli nie podano $else, zwracana jest 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

Ta metoda jest przydatna, gdy trzeba szybko pobrać pierwszy element kolekcji lub pierwszy element spełniający określony warunek bez ręcznego iterowania przez całą kolekcję.

firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null)mixed

Zwraca klucz pierwszego elementu iteratora. Jeśli podano $predicate, zwraca klucz pierwszego elementu, który spełnia podany warunek. Funkcja $predicate ma sygnaturę function ($value, $key, iterable $iterable): bool. Jeśli nie zostanie znaleziony żaden pasujący element, wywoływana jest funkcja $else (jeśli została podana) i zwracany jest jej wynik. Jeśli nie podano $else, zwracana jest 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

Tworzy nowy iterator poprzez zastosowanie funkcji $transformer do każdego elementu oryginalnego iteratora. Funkcja $transformer ma sygnaturę function ($value, $key, iterable $iterable): mixed, a jej wartość zwracana jest używana jako nowa wartość elementu.

$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::map($iterator, fn($v) => $v * 2);
// 2, 4, 6

Metoda ta wykorzystuje generator, co oznacza, że transformacja odbywa się przyrostowo podczas iteracji. Jest to wydajne pod względem pamięci i pozwala na obsługę bardzo dużych kolekcji. Jeśli nie iterujesz przez wszystkie elementy wynikowego iteratora, oszczędzasz wysiłek obliczeniowy, ponieważ nie wszystkie elementy oryginalnego iteratora są przetwarzane.

mapWithKeys (iterable $iterable, callable $transformer): Generator

Tworzy nowy iterator poprzez przekształcenie wartości i kluczy oryginalnego iteratora. Funkcja $transformer ma sygnaturę function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}. Jeśli $transformer zwróci null, element jest pomijany. Dla zachowanych elementów, pierwszy element zwróconej tablicy jest używany jako nowy klucz, a drugi element jako nowa wartość.

$iterator = new ArrayIterator(['a' => 1, 'b' => 2]);
$iterator = Iterables::mapWithKeys($iterator, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']

Podobnie jak map(), metoda ta wykorzystuje generator do przetwarzania przyrostowego i wydajności pamięci. Pozwala to na pracę z dużymi kolekcjami i oszczędność wysiłku obliczeniowego poprzez przetwarzanie tylko części wyniku.

memoize (iterable $iterable): IteratorAggregate

Tworzy opakowanie wokół iteratora, które buforuje jego klucze i wartości podczas iteracji. Pozwala to na wielokrotną iterację danych bez konieczności ponownego przetwarzania oryginalnego źródła danych.

$iterator = /* data that cannot be iterated multiple times */
$memoized = Iterables::memoize($iterator);
// Now you can iterate $memoized multiple times without data loss

Metoda ta jest przydatna w sytuacjach, gdy trzeba wielokrotnie iterować po tym samym zestawie danych, ale oryginalny iterator nie obsługuje wielokrotnej iteracji lub wielokrotna iteracja byłaby kosztowna (np. odczytywanie danych z bazy danych lub pliku).

some (iterable $iterable, callable $predicate)bool

Sprawdza, czy co najmniej jeden element iteratora spełnia warunek zdefiniowany w $predicate. Funkcja $predicate ma sygnaturę function ($value, $key, iterable $iterable): bool i musi zwrócić true dla co najmniej jednego elementu, aby metoda some() zwróciła true.

$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isEven = fn($value) => $value % 2 === 0;
$res = Iterables::some($iterator, $isEven); // true

Metoda ta jest przydatna do szybkiego sprawdzenia, czy w kolekcji znajduje się co najmniej jeden element spełniający określony warunek, np. czy kolekcja zawiera co najmniej jedną liczbę parzystą.

Zobacz every().

toIterator (iterable $iterable): Iterator

Konwertuje dowolny obiekt iterowalny (tablicę, Traversable) na Iterator. Jeśli dane wejściowe są już Iteratorem, są zwracane bez zmian.

$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Now you have an Iterator instead of an array

Ta metoda jest przydatna, gdy trzeba upewnić się, że mamy Iterator, niezależnie od typu danych wejściowych. Może to być przydatne podczas tworzenia funkcji, które działają z różnymi typami danych iterowalnych.

wersja: 4.0