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.

versión: 4.0