Praca z iteratorami
Nette\Utils\Iterables to klasa statyczna z funkcjami do pracy z iteratorami. Jej odpowiednikiem dla tablic jest Nette\Utils\Arrays.
Instalacja:
composer require nette/utils
Wszystkie przykłady zakładają utworzony alias:
use Nette\Utils\Iterables;
contains (iterable $iterable, $value): bool
Szuka podanej wartości w iteratorze. Używa ścisłego porównania (===
) do sprawdzenia zgodności. 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 potrzebujesz szybko sprawdzić, czy określona wartość znajduje się w iteratorze, bez konieczności ręcznego przeglądania wszystkich elementów.
containsKey (iterable $iterable, $key): bool
Szuka podanego klucza w iteratorze. Używa ścisłego porównania (===
) do sprawdzenia zgodności. Zwraca
true
, jeśli klucz zostanie 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 zwracać
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
Ta metoda jest przydatna do sprawdzenia, czy wszystkie elementy w kolekcji spełniają określony warunek, na przykład czy wszystkie liczby są mniejsze od 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 mają
być 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ę stopniowo podczas przeglądania wyniku. Jest to efektywne pod względem pamięci i pozwala przetwarzać nawet bardzo duże kolekcje. Jeśli nie przejdziesz wszystkich elementów wynikowego iteratora, oszczędzisz moc obliczeniową, ponieważ nie przetworzą się wszystkie elementy oryginalnego iteratora.
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
znaleziono żadnego pasującego elementu, wywoływana jest funkcja $else
(jeśli jest podana) i zwracany jest jej
wynik. Jeśli $else
nie jest podane, zwracane 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 potrzebujesz szybko uzyskać pierwszy element kolekcji lub pierwszy element spełniający określony warunek, bez konieczności ręcznego przeglądania całej kolekcji.
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 znaleziono żadnego pasującego elementu, wywoływana
jest funkcja $else
(jeśli jest podana) i zwracany jest jej wynik. Jeśli $else
nie jest podane,
zwracane 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, stosując funkcję $transformer
do każdego elementu oryginalnego iteratora. Funkcja
$transformer
ma sygnaturę function ($value, $key, iterable $iterable): mixed
i 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 wykorzystuje generator, co oznacza, że transformacja odbywa się stopniowo podczas przeglądania wyniku. Jest to efektywne pod względem pamięci i pozwala przetwarzać nawet bardzo duże kolekcje. Jeśli nie przejdziesz wszystkich elementów wynikowego iteratora, oszczędzisz moc obliczeniową, ponieważ nie przetworzą się wszystkie elementy oryginalnego iteratora.
mapWithKeys (iterable $iterable, callable $transformer): Generator
Tworzy nowy iterator, transformując wartości i klucze 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()
, ta metoda wykorzystuje generator do stopniowego przetwarzania i efektywnej pracy
z pamięcią. Pozwala to pracować z dużymi kolekcjami i oszczędzać moc obliczeniową przy częściowym przejściu
przez wynik.
memoize (iterable $iterable): IteratorAggregate
Tworzy opakowanie wokół iteratora, które podczas iteracji zapisuje w pamięci podręcznej jego klucze i wartości. Pozwala to na wielokrotną iterację danych bez konieczności ponownego przechodzenia przez oryginalne źródło danych.
$iterator = /* dane, których nie można iterować wielokrotnie */
$memoized = Iterables::memoize($iterator);
// Teraz możesz iterować $memoized wielokrotnie bez utraty danych
Ta metoda jest przydatna w sytuacjach, gdy potrzebujesz wielokrotnie przejść przez ten sam zestaw danych, ale oryginalny iterator nie pozwala na wielokrotną iterację lub ponowne przejście byłoby kosztowne (np. przy odczycie danych z bazy danych lub pliku).
some (iterable $iterable, callable $predicate): bool
Sprawdza, czy przynajmniej jeden element iteratora spełnia warunek zdefiniowany w $predicate
. Funkcja
$predicate
ma sygnaturę function ($value, $key, iterable $iterable): bool
i musi zwracać
true
dla przynajmniej 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
Ta metoda jest przydatna do szybkiego sprawdzenia, czy w kolekcji istnieje przynajmniej jeden element spełniający określony warunek, na przykład czy kolekcja zawiera przynajmniej jedną liczbę parzystą.
Zobacz every().
toIterator (iterable $iterable): Iterator
Konwertuje dowolny obiekt iterowalny (array, Traversable) na Iterator. Jeśli wejście jest już Iteratorem, zwraca go bez zmian.
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Teraz masz Iterator zamiast tablicy
Ta metoda jest przydatna, gdy potrzebujesz zapewnić, że masz do dyspozycji Iterator, niezależnie od typu danych wejściowych. Może to być przydatne przy tworzeniu funkcji, które pracują z różnymi typami danych iterowalnych.