Funciones de iteración
Nette\Utils\Iterables es una clase estática con funciones para trabajar con iteradores. Su contrapartida para arrays es Nette\Utils\Arrays.
Instalación:
composer require nette/utils
Todos los ejemplos suponen que se ha creado el siguiente alias:
use Nette\Utils\Iterables;
contains (iterable $iterable, $value): bool
Busca un valor dado en un iterador. Utiliza la comparación estricta (===
) para buscar una coincidencia. Devuelve
true
si se encuentra el valor, en caso 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 se necesita determinar rápidamente si un valor específico está presente en un iterador sin iterar manualmente a través de todos los elementos.
containsKey (iterable $iterable, $key): bool
Busca una clave dada en un iterador. Utiliza la comparación estricta (===
) para buscar una coincidencia. Devuelve
true
si se encuentra la clave, en caso 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
Comprueba 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 que todos los elementos de una colección cumplen una determinada condición, como por ejemplo si todos los números están por debajo de un valor específico.
filter (iterable $iterable, callable $predicate): Generator
Crea un nuevo iterador que contiene sólo los elementos del iterador original que satisfacen 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 deben
conservarse.
$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 produce de forma incremental durante la iteración. Esto es eficiente en memoria y permite manejar colecciones muy grandes. Si no se itera por todos los elementos del iterador resultante, se ahorra esfuerzo computacional, ya que no se procesan todos los elementos del iterador original.
first (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Devuelve el primer elemento del iterador. Si se proporciona $predicate
, devuelve el primer elemento que satisface
la condición dada. La función $predicate
tiene la firma
function ($value, $key, iterable $iterable): bool
. Si no se encuentra ningún elemento coincidente, se llama a la
función $else
(si se proporciona) y se devuelve su resultado. Si no se proporciona $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 se necesita recuperar rápidamente el primer elemento de una colección o el primer elemento que cumple una determinada condición sin iterar manualmente por toda la colección.
firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
Devuelve la clave del primer elemento del iterador. Si se proporciona $predicate
, devuelve la clave del primer
elemento que satisface la condición dada. La función $predicate
tiene la firma
function ($value, $key, iterable $iterable): bool
. Si no se encuentra ningún elemento coincidente, se llama a la
función $else
(si se proporciona) y se devuelve su resultado. Si no se proporciona $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 produce de forma incremental durante la iteración. Esto es eficiente en memoria y permite manejar colecciones muy grandes. Si no se itera por todos los elementos del iterador resultante, se ahorra esfuerzo computacional, ya que no se procesan 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 retenidos, 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 incremental y la eficiencia de
memoria. Esto permite trabajar con grandes colecciones y ahorrar esfuerzo computacional procesando sólo una parte del
resultado.
memoize (iterable $iterable): IteratorAggregate
Crea una envoltura alrededor de un iterador que almacena en caché sus claves y valores durante la iteración. Esto permite repetir la iteración sobre los datos sin tener que reprocesar la fuente de datos original.
$iterator = /* data that cannot be iterated multiple times */
$memoized = Iterables::memoize($iterator);
// Now you can iterate $memoized multiple times without data loss
Este método es útil en situaciones en las que se necesita iterar sobre el mismo conjunto de datos varias veces, pero el iterador original no soporta la iteración repetida o la iteración repetida sería costosa (por ejemplo, la lectura de datos de una base de datos o archivo).
some (iterable $iterable, callable $predicate): bool
Comprueba 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 hay al menos un elemento en una colección que cumpla una determinada condición, como por ejemplo si la colección contiene al menos un número par.
Véase every().
toIterator (iterable $iterable): Iterator
Convierte cualquier objeto iterable (array, Traversable) en un Iterator. Si la entrada ya es un Iterador, se devuelve sin cambios.
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Now you have an Iterator instead of an array
Este método es útil cuando necesitas asegurarte de que tienes un Iterator, independientemente del tipo de datos de entrada. Esto puede ser útil cuando se crean funciones que trabajan con diferentes tipos de datos iterables.