Iterator Functions

Nette\Utils\Iterables is a static class with functions for working with iterators. Its counterpart for arrays is Nette\Utils\Arrays.

Installation:

composer require nette/utils

All examples assume the following alias is created:

use Nette\Utils\Iterables;

contains (iterable $iterable, $value)bool

Searches for a given value in an iterator. Uses strict comparison (===) to check for a match. Returns true if the value is found, otherwise false.

Iterables::contains(new ArrayIterator([1, 2, 3]), 1);    // true
Iterables::contains(new ArrayIterator([1, 2, 3]), '1');  // false

This method is useful when you need to quickly determine if a specific value is present in an iterator without manually iterating through all elements.

containsKey (iterable $iterable, $key)bool

Searches for a given key in an iterator. Uses strict comparison (===) to check for a match. Returns true if the key is found, otherwise 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

Checks if all elements of the iterator satisfy the condition defined in $predicate. The function $predicate has the signature function ($value, $key, iterable $iterable): bool and must return true for every element for the every() method to return true.

$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isBelowThreshold = fn($value) => $value < 40;
$res = Iterables::every($iterator, $isBelowThreshold); // true

This method is useful for verifying that all elements in a collection meet a certain condition, such as whether all numbers are below a specific value.

filter (iterable $iterable, callable $predicate): Generator

Creates a new iterator that contains only the elements from the original iterator that satisfy the condition defined in $predicate. The function $predicate has the signature function ($value, $key, iterable $iterable): bool and must return true for elements that should be retained.

$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::filter($iterator, fn($v) => $v < 3);
// 1, 2

The method uses a generator, meaning that filtering occurs incrementally during iteration. This is memory efficient and allows for handling very large collections. If you do not iterate through all elements of the resulting iterator, you save computational effort since not all elements of the original iterator are processed.

first (iterable $iterable, ?callable $predicate=null, ?callable $else=null)mixed

Returns the first element of the iterator. If $predicate is provided, it returns the first element that satisfies the given condition. The function $predicate has the signature function ($value, $key, iterable $iterable): bool. If no matching element is found, the $else function (if provided) is called and its result is returned. If $else is not provided, null is returned.

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

This method is useful when you need to quickly retrieve the first element of a collection or the first element that meets a certain condition without manually iterating through the entire collection.

firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null)mixed

Returns the key of the first element of the iterator. If $predicate is provided, it returns the key of the first element that satisfies the given condition. The function $predicate has the signature function ($value, $key, iterable $iterable): bool. If no matching element is found, the $else function (if provided) is called and its result is returned. If $else is not provided, null is returned.

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

Creates a new iterator by applying the $transformer function to each element of the original iterator. The function $transformer has the signature function ($value, $key, iterable $iterable): mixed and its return value is used as the new value of the element.

$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::map($iterator, fn($v) => $v * 2);
// 2, 4, 6

The method uses a generator, meaning that the transformation occurs incrementally during iteration. This is memory efficient and allows for handling very large collections. If you do not iterate through all elements of the resulting iterator, you save computational effort since not all elements of the original iterator are processed.

mapWithKeys (iterable $iterable, callable $transformer): Generator

Creates a new iterator by transforming the values and keys of the original iterator. The function $transformer has the signature function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}. If $transformer returns null, the element is skipped. For retained elements, the first element of the returned array is used as the new key and the second element as the new value.

$iterator = new ArrayIterator(['a' => 1, 'b' => 2]);
$iterator = Iterables::mapWithKeys($iterator, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']

Like map(), this method uses a generator for incremental processing and memory efficiency. This allows working with large collections and saving computational effort by processing only part of the result.

memoize (iterable $iterable): IteratorAggregate

Creates a wrapper around an iterator that caches its keys and values during iteration. This allows for repeated iteration over the data without having to reprocess the original data source.

$iterator = /* data that cannot be iterated multiple times */
$memoized = Iterables::memoize($iterator);
// Now you can iterate $memoized multiple times without data loss

This method is useful in situations where you need to iterate over the same set of data multiple times, but the original iterator does not support repeated iteration or repeated iteration would be costly (e.g., reading data from a database or file).

some (iterable $iterable, callable $predicate)bool

Checks if at least one element of the iterator satisfies the condition defined in $predicate. The function $predicate has the signature function ($value, $key, iterable $iterable): bool and must return true for at least one element for the some() method to return true.

$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isEven = fn($value) => $value % 2 === 0;
$res = Iterables::some($iterator, $isEven); // true

This method is useful for quickly verifying if there is at least one element in a collection that meets a certain condition, such as whether the collection contains at least one even number.

See every().

toIterator (iterable $iterable): Iterator

Converts any iterable object (array, Traversable) to an Iterator. If the input is already an Iterator, it is returned unchanged.

$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Now you have an Iterator instead of an array

This method is useful when you need to ensure that you have an Iterator, regardless of the input data type. This can be useful when creating functions that work with different types of iterable data.

version: 4.0