Trabajando con iteradores
Nette\Utils\Iterables es una clase estática con funciones para trabajar con iteradores. Su contraparte para arrays es Nette\Utils\Arrays.
Instalación:
composer require nette/utils
Todos los ejemplos asumen que se ha creado un alias:
use Nette\Utils\Iterables;
contains (iterable $iterable, $value): bool
Busca un valor específico en el iterador. Utiliza una comparación estricta (===
) para verificar la coincidencia.
Devuelve true
si se encuentra el valor, de lo contrario false
.
Iterables::contains(new ArrayIterator([1, 2, 3]), 1); // true
Iterables::contains(new ArrayIterator([1, 2, 3]), '1'); // false
Este método es útil cuando necesita determinar rápidamente si un valor particular está presente en el iterador sin tener que recorrer manualmente todos los elementos.
containsKey (iterable $iterable, $key): bool
Busca una clave específica en el iterador. Utiliza una comparación estricta (===
) para verificar la
coincidencia. Devuelve true
si se encuentra la clave, de lo contrario 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 si todos los elementos del iterador cumplen la condición definida en $predicate
. La función
$predicate
tiene la firma function ($value, $key, iterable $iterable): bool
y debe devolver
true
para cada elemento para que el método every()
devuelva true
.
$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isBelowThreshold = fn($value) => $value < 40;
$res = Iterables::every($iterator, $isBelowThreshold); // true
Este método es útil para verificar si todos los elementos de una colección cumplen una determinada condición, por ejemplo, si todos los números son menores que un valor determinado.
filter (iterable $iterable, callable $predicate): Generator
Crea un nuevo iterador que contiene solo aquellos elementos del iterador original que cumplen la condición definida en
$predicate
. La función $predicate
tiene la firma
function ($value, $key, iterable $iterable): bool
y debe devolver true
para los elementos que se deben
conservar.
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::filter($iterator, fn($v) => $v < 3);
// 1, 2
El método utiliza un generador, lo que significa que el filtrado se realiza gradualmente al recorrer el resultado. Esto es eficiente en términos de memoria y permite procesar colecciones muy grandes. Si no recorre todos los elementos del iterador resultante, ahorrará potencia de cálculo, ya que no se procesarán todos los elementos del iterador original.
first (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Devuelve el primer elemento del iterador. Si se especifica $predicate
, devuelve el primer elemento que cumple la
condición dada. La función $predicate
tiene la firma
function ($value, $key, iterable $iterable): bool
. Si no se encuentra ningún elemento que coincida, se llama a la
función $else
(si se especifica) y se devuelve su resultado. Si no se especifica $else
, se devuelve
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 es útil cuando necesita obtener rápidamente el primer elemento de una colección o el primer elemento que cumple una determinada condición, sin tener que recorrer manualmente toda la colección.
firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Devuelve la clave del primer elemento del iterador. Si se especifica $predicate
, devuelve la clave del primer
elemento que cumple la condición dada. La función $predicate
tiene la firma
function ($value, $key, iterable $iterable): bool
. Si no se encuentra ningún elemento que coincida, se llama a la
función $else
(si se especifica) y se devuelve su resultado. Si no se especifica $else
, se devuelve
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
Crea un nuevo iterador aplicando la función $transformer
a cada elemento del iterador original. La función
$transformer
tiene la firma function ($value, $key, iterable $iterable): mixed
y su valor de retorno se
utiliza como el nuevo valor del elemento.
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::map($iterator, fn($v) => $v * 2);
// 2, 4, 6
El método utiliza un generador, lo que significa que la transformación se realiza gradualmente al recorrer el resultado. Esto es eficiente en términos de memoria y permite procesar colecciones muy grandes. Si no recorre todos los elementos del iterador resultante, ahorrará potencia de cálculo, ya que no se procesarán todos los elementos del iterador original.
mapWithKeys (iterable $iterable, callable $transformer): Generator
Crea un nuevo iterador transformando los valores y claves del iterador original. La función $transformer
tiene la
firma function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}
. Si $transformer
devuelve
null
, el elemento se omite. Para los elementos conservados, el primer elemento del array devuelto se utiliza como la
nueva clave y el segundo elemento como el nuevo valor.
$iterator = new ArrayIterator(['a' => 1, 'b' => 2]);
$iterator = Iterables::mapWithKeys($iterator, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Al igual que map()
, este método utiliza un generador para el procesamiento gradual y el trabajo eficiente con la
memoria. Esto permite trabajar con colecciones grandes y ahorrar potencia de cálculo en el recorrido parcial del resultado.
memoize (iterable $iterable): IteratorAggregate
Crea un envoltorio alrededor de un iterador que almacena en caché sus claves y valores durante la iteración. Esto permite la iteración repetida de datos sin necesidad de volver a recorrer la fuente de datos original.
$iterator = /* datos que no se pueden iterar más de una vez */
$memoized = Iterables::memoize($iterator);
// Ahora puedes iterar $memoized varias veces sin perder datos
Este método es útil en situaciones en las que necesita recorrer el mismo conjunto de datos varias veces, pero el iterador original no permite la iteración repetida o el recorrido repetido sería costoso (por ejemplo, al leer datos de una base de datos o un archivo).
some (iterable $iterable, callable $predicate): bool
Verifica si al menos un elemento del iterador cumple la condición definida en $predicate
. La función
$predicate
tiene la firma function ($value, $key, iterable $iterable): bool
y debe devolver
true
para al menos un elemento para que el método some()
devuelva 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 es útil para verificar rápidamente si existe al menos un elemento en la colección que cumpla una determinada condición, por ejemplo, si la colección contiene al menos un número par.
Ver every().
toIterator (iterable $iterable): Iterator
Convierte cualquier objeto iterable (array, Traversable) en un Iterator. Si la entrada ya es un Iterator, lo devuelve sin cambios.
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Ahora tienes un Iterator en lugar de un array
Este método es útil cuando necesita asegurarse de que tiene un Iterator disponible, independientemente del tipo de datos de entrada. Esto puede ser útil al crear funciones que trabajan con diferentes tipos de datos iterables.