Trabalhando com iteradores
Nette\Utils\Iterables é uma classe estática com funções para trabalhar com iteradores. Seu equivalente para arrays é Nette\Utils\Arrays.
Instalação:
composer require nette/utils
Todos os exemplos assumem que um alias foi criado:
use Nette\Utils\Iterables;
contains (iterable $iterable, $value): bool
Procura o valor especificado no iterador. Usa comparação estrita (===
) para verificar a correspondência.
Retorna true
se o valor for encontrado, caso contrário false
.
Iterables::contains(new ArrayIterator([1, 2, 3]), 1); // true
Iterables::contains(new ArrayIterator([1, 2, 3]), '1'); // false
Este método é útil quando você precisa descobrir rapidamente se um valor específico está no iterador sem ter que percorrer todos os elementos manualmente.
containsKey (iterable $iterable, $key): bool
Procura a chave especificada no iterador. Usa comparação estrita (===
) para verificar a correspondência.
Retorna true
se a chave for encontrada, caso contrário 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
Verifica se todos os elementos do iterador satisfazem a condição definida em $predicate
. A função
$predicate
tem a assinatura function ($value, $key, iterable $iterable): bool
e deve retornar
true
para cada elemento para que o método every()
retorne true
.
$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isBelowThreshold = fn($value) => $value < 40;
$res = Iterables::every($iterator, $isBelowThreshold); // true
Este método é útil para verificar se todos os elementos em uma coleção satisfazem uma determinada condição, por exemplo, se todos os números são menores que um determinado valor.
filter (iterable $iterable, callable $predicate): Generator
Cria um novo iterador que contém apenas os elementos do iterador original que satisfazem a condição definida em
$predicate
. A função $predicate
tem a assinatura
function ($value, $key, iterable $iterable): bool
e deve retornar true
para os elementos que devem ser
mantidos.
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::filter($iterator, fn($v) => $v < 3);
// 1, 2
O método utiliza um gerador, o que significa que a filtragem ocorre gradualmente ao percorrer o resultado. Isso é eficiente em termos de memória e permite processar coleções muito grandes. Se você não percorrer todos os elementos do iterador resultante, economizará poder de processamento, pois nem todos os elementos do iterador original serão processados.
first (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Retorna o primeiro elemento do iterador. Se $predicate
for especificado, retorna o primeiro elemento que
satisfaz a condição dada. A função $predicate
tem a assinatura
function ($value, $key, iterable $iterable): bool
. Se nenhum elemento correspondente for encontrado, a função
$else
é chamada (se especificada) e seu resultado é retornado. Se $else
não for especificado, retorna
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
Este método é útil quando você precisa obter rapidamente o primeiro elemento de uma coleção ou o primeiro elemento que satisfaz uma determinada condição, sem ter que percorrer toda a coleção manualmente.
firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Retorna a chave do primeiro elemento do iterador. Se $predicate
for especificado, retorna a chave do primeiro
elemento que satisfaz a condição dada. A função $predicate
tem a assinatura
function ($value, $key, iterable $iterable): bool
. Se nenhum elemento correspondente for encontrado, a função
$else
é chamada (se especificada) e seu resultado é retornado. Se $else
não for especificado, retorna
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
Cria um novo iterador aplicando a função $transformer
a cada elemento do iterador original. A função
$transformer
tem a assinatura function ($value, $key, iterable $iterable): mixed
e seu valor de retorno
é usado como o novo valor do elemento.
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::map($iterator, fn($v) => $v * 2);
// 2, 4, 6
O método utiliza um gerador, o que significa que a transformação ocorre gradualmente ao percorrer o resultado. Isso é eficiente em termos de memória e permite processar coleções muito grandes. Se você não percorrer todos os elementos do iterador resultante, economizará poder de processamento, pois nem todos os elementos do iterador original serão processados.
mapWithKeys (iterable $iterable, callable $transformer): Generator
Cria um novo iterador transformando os valores e chaves do iterador original. A função $transformer
tem a
assinatura function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}
. Se $transformer
retornar null
, o elemento é ignorado. Para os elementos mantidos, o primeiro elemento do array retornado é usado
como a nova chave e o segundo elemento como o novo valor.
$iterator = new ArrayIterator(['a' => 1, 'b' => 2]);
$iterator = Iterables::mapWithKeys($iterator, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Assim como map()
, este método utiliza um gerador para processamento gradual e trabalho eficiente com a memória.
Isso permite trabalhar com grandes coleções e economizar poder de processamento ao percorrer parcialmente o resultado.
memoize (iterable $iterable): IteratorAggregate
Cria um invólucro em torno do iterador que armazena em cache suas chaves e valores durante a iteração. Isso permite a iteração repetida dos dados sem a necessidade de percorrer novamente a fonte de dados original.
$iterator = /* dados que não podem ser iterados mais de uma vez */
$memoized = Iterables::memoize($iterator);
// Agora você pode iterar $memoized várias vezes sem perder dados
Este método é útil em situações em que você precisa percorrer o mesmo conjunto de dados várias vezes, mas o iterador original não permite iteração repetida ou a passagem repetida seria cara (por exemplo, ao ler dados de um banco de dados ou arquivo).
some (iterable $iterable, callable $predicate): bool
Verifica se pelo menos um elemento do iterador satisfaz a condição definida em $predicate
. A função
$predicate
tem a assinatura function ($value, $key, iterable $iterable): bool
e deve retornar
true
para pelo menos um elemento para que o método some()
retorne true
.
$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isEven = fn($value) => $value % 2 === 0;
$res = Iterables::some($iterator, $isEven); // true
Este método é útil para verificar rapidamente se existe pelo menos um elemento na coleção que satisfaz uma determinada condição, por exemplo, se a coleção contém pelo menos um número par.
Veja every().
toIterator (iterable $iterable): Iterator
Converte qualquer objeto iterável (array, Traversable) em um Iterator. Se a entrada já for um Iterator, retorna-o sem alterações.
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Agora você tem um Iterator em vez de um array
Este método é útil quando você precisa garantir que tem um Iterator disponível, independentemente do tipo de dados de entrada. Isso pode ser útil ao criar funções que trabalham com diferentes tipos de dados iteráveis.