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.