Nette Documentation Preview

syntax
Работа с итераторами
********************

.[perex]{data-version:4.0.4}
[api:Nette\Utils\Iterables] - это статический класс с функциями для работы с итераторами. Его аналогом для массивов является [Nette\Utils\Arrays|arrays].


Установка:

```shell
composer require nette/utils
```

Все примеры предполагают, что создан псевдоним:

```php
use Nette\Utils\Iterables;
```


contains(iterable $iterable, $value): bool .[method]
----------------------------------------------------

Ищет указанное значение в итераторе. Использует строгое сравнение (`===`) для проверки совпадения. Возвращает `true`, если значение найдено, иначе `false`.

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

Этот метод полезен, когда нужно быстро определить, находится ли конкретное значение в итераторе, без необходимости проходить все элементы вручную.


containsKey(iterable $iterable, $key): bool .[method]
-----------------------------------------------------

Ищет указанный ключ в итераторе. Использует строгое сравнение (`===`) для проверки совпадения. Возвращает `true`, если ключ найден, иначе `false`.

```php
Iterables::containsKey(new ArrayIterator([1, 2, 3]), 0);  // true
Iterables::containsKey(new ArrayIterator([1, 2, 3]), 4);  // false
```


every(iterable $iterable, callable $predicate): bool .[method]
--------------------------------------------------------------

Проверяет, все ли элементы итератора удовлетворяют условию, определенному в `$predicate`. Функция `$predicate` имеет сигнатуру `function ($value, $key, iterable $iterable): bool` и должна возвращать `true` для каждого элемента, чтобы метод `every()` вернул `true`.

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

Этот метод полезен для проверки, удовлетворяют ли все элементы в коллекции определенному условию, например, все ли числа меньше определенного значения.


filter(iterable $iterable, callable $predicate): Generator .[method]
--------------------------------------------------------------------

Создает новый итератор (генератор), который содержит только те элементы из исходного итератора, которые удовлетворяют условию, определенному в `$predicate`. Функция `$predicate` имеет сигнатуру `function ($value, $key, iterable $iterable): bool` и должна возвращать `true` для элементов, которые должны быть сохранены.

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

Метод использует генератор, что означает, что фильтрация происходит постепенно при прохождении результата. Это эффективно с точки зрения памяти и позволяет обрабатывать даже очень большие коллекции. Если вы не пройдете все элементы результирующего итератора, вы сэкономите вычислительную мощность, так как не все элементы исходного итератора будут обработаны.


first(iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed .[method]
-------------------------------------------------------------------------------------------

Возвращает первый элемент итератора. Если указан `$predicate`, возвращает первый элемент, удовлетворяющий данному условию. Функция `$predicate` имеет сигнатуру `function ($value, $key, iterable $iterable): bool`. Если не найден ни один подходящий элемент, вызывается функция `$else` (если она указана) и возвращается ее результат. Если `$else` не указано, возвращается `null`.

```php
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
```

Этот метод полезен, когда нужно быстро получить первый элемент коллекции или первый элемент, удовлетворяющий определенному условию, без необходимости проходить всю коллекцию вручную.


firstKey(iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed .[method]
----------------------------------------------------------------------------------------------

Возвращает ключ первого элемента итератора. Если указан `$predicate`, возвращает ключ первого элемента, удовлетворяющего данному условию. Функция `$predicate` имеет сигнатуру `function ($value, $key, iterable $iterable): bool`. Если не найден ни один подходящий элемент, вызывается функция `$else` (если она указана) и возвращается ее результат. Если `$else` не указано, возвращается `null`.

```php
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 .[method]
-------------------------------------------------------------------

Создает новый итератор (генератор), применяя функцию `$transformer` к каждому элементу исходного итератора. Функция `$transformer` имеет сигнатуру `function ($value, $key, iterable $iterable): mixed`, и ее возвращаемое значение используется как новое значение элемента.

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

Метод использует генератор, что означает, что трансформация происходит постепенно при прохождении результата. Это эффективно с точки зрения памяти и позволяет обрабатывать даже очень большие коллекции. Если вы не пройдете все элементы результирующего итератора, вы сэкономите вычислительную мощность, так как не все элементы исходного итератора будут обработаны.


mapWithKeys(iterable $iterable, callable $transformer): Generator .[method]
---------------------------------------------------------------------------

Создает новый итератор (генератор) путем трансформации значений и ключей исходного итератора. Функция `$transformer` имеет сигнатуру `function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}`. Если `$transformer` возвращает `null`, элемент пропускается. Для сохраненных элементов первый элемент возвращенного массива используется как новый ключ, а второй элемент - как новое значение.

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

Как и `map()`, этот метод использует генератор для постепенной обработки и эффективной работы с памятью. Это позволяет работать с большими коллекциями и экономить вычислительную мощность при частичном прохождении результата.


memoize(iterable $iterable): IteratorAggregate .[method]
--------------------------------------------------------

Создает обертку вокруг итератора, которая во время итерации кеширует его ключи и значения. Это позволяет повторно итерировать данные без необходимости снова проходить исходный источник данных.

```php
$iterator = /* данные, которые нельзя итерировать несколько раз */
$memoized = Iterables::memoize($iterator);
// Теперь вы можете итерировать $memoized несколько раз без потери данных
```

Этот метод полезен в ситуациях, когда вам нужно несколько раз пройти один и тот же набор данных, но исходный итератор не позволяет повторную итерацию или повторное прохождение было бы затратным (например, при чтении данных из базы данных или файла).


some(iterable $iterable, callable $predicate): bool .[method]
-------------------------------------------------------------

Проверяет, удовлетворяет ли хотя бы один элемент итератора условию, определенному в `$predicate`. Функция `$predicate` имеет сигнатуру `function ($value, $key, iterable $iterable): bool` и должна возвращать `true` хотя бы для одного элемента, чтобы метод `some()` вернул `true`.

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

Этот метод полезен для быстрой проверки, существует ли в коллекции хотя бы один элемент, удовлетворяющий определенному условию, например, содержит ли коллекция хотя бы одно четное число.

См. [#every()].


toIterator(iterable $iterable): Iterator .[method]
--------------------------------------------------

Преобразует любой итерируемый объект (array, Traversable) в Iterator. Если входные данные уже являются Iterator, возвращает их без изменений.

```php
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Теперь у вас есть Iterator вместо массива
```

Этот метод полезен, когда нужно убедиться, что у вас есть Iterator, независимо от типа входных данных. Это может быть полезно при создании функций, которые работают с различными типами итерируемых данных.

Работа с итераторами

Nette\Utils\Iterables – это статический класс с функциями для работы с итераторами. Его аналогом для массивов является Nette\Utils\Arrays.

Установка:

composer require nette/utils

Все примеры предполагают, что создан псевдоним:

use Nette\Utils\Iterables;

contains(iterable $iterable, $value)bool

Ищет указанное значение в итераторе. Использует строгое сравнение (===) для проверки совпадения. Возвращает true, если значение найдено, иначе false.

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

Этот метод полезен, когда нужно быстро определить, находится ли конкретное значение в итераторе, без необходимости проходить все элементы вручную.

containsKey(iterable $iterable, $key)bool

Ищет указанный ключ в итераторе. Использует строгое сравнение (===) для проверки совпадения. Возвращает true, если ключ найден, иначе 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

Проверяет, все ли элементы итератора удовлетворяют условию, определенному в $predicate. Функция $predicate имеет сигнатуру function ($value, $key, iterable $iterable): bool и должна возвращать true для каждого элемента, чтобы метод every() вернул true.

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

Этот метод полезен для проверки, удовлетворяют ли все элементы в коллекции определенному условию, например, все ли числа меньше определенного значения.

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

Создает новый итератор (генератор), который содержит только те элементы из исходного итератора, которые удовлетворяют условию, определенному в $predicate. Функция $predicate имеет сигнатуру function ($value, $key, iterable $iterable): bool и должна возвращать true для элементов, которые должны быть сохранены.

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

Метод использует генератор, что означает, что фильтрация происходит постепенно при прохождении результата. Это эффективно с точки зрения памяти и позволяет обрабатывать даже очень большие коллекции. Если вы не пройдете все элементы результирующего итератора, вы сэкономите вычислительную мощность, так как не все элементы исходного итератора будут обработаны.

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

Возвращает первый элемент итератора. Если указан $predicate, возвращает первый элемент, удовлетворяющий данному условию. Функция $predicate имеет сигнатуру function ($value, $key, iterable $iterable): bool. Если не найден ни один подходящий элемент, вызывается функция $else (если она указана) и возвращается ее результат. Если $else не указано, возвращается 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

Этот метод полезен, когда нужно быстро получить первый элемент коллекции или первый элемент, удовлетворяющий определенному условию, без необходимости проходить всю коллекцию вручную.

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

Возвращает ключ первого элемента итератора. Если указан $predicate, возвращает ключ первого элемента, удовлетворяющего данному условию. Функция $predicate имеет сигнатуру function ($value, $key, iterable $iterable): bool. Если не найден ни один подходящий элемент, вызывается функция $else (если она указана) и возвращается ее результат. Если $else не указано, возвращается 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

Создает новый итератор (генератор), применяя функцию $transformer к каждому элементу исходного итератора. Функция $transformer имеет сигнатуру function ($value, $key, iterable $iterable): mixed, и ее возвращаемое значение используется как новое значение элемента.

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

Метод использует генератор, что означает, что трансформация происходит постепенно при прохождении результата. Это эффективно с точки зрения памяти и позволяет обрабатывать даже очень большие коллекции. Если вы не пройдете все элементы результирующего итератора, вы сэкономите вычислительную мощность, так как не все элементы исходного итератора будут обработаны.

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

Создает новый итератор (генератор) путем трансформации значений и ключей исходного итератора. Функция $transformer имеет сигнатуру function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}. Если $transformer возвращает null, элемент пропускается. Для сохраненных элементов первый элемент возвращенного массива используется как новый ключ, а второй элемент – как новое значение.

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

Как и map(), этот метод использует генератор для постепенной обработки и эффективной работы с памятью. Это позволяет работать с большими коллекциями и экономить вычислительную мощность при частичном прохождении результата.

memoize(iterable $iterable): IteratorAggregate

Создает обертку вокруг итератора, которая во время итерации кеширует его ключи и значения. Это позволяет повторно итерировать данные без необходимости снова проходить исходный источник данных.

$iterator = /* данные, которые нельзя итерировать несколько раз */
$memoized = Iterables::memoize($iterator);
// Теперь вы можете итерировать $memoized несколько раз без потери данных

Этот метод полезен в ситуациях, когда вам нужно несколько раз пройти один и тот же набор данных, но исходный итератор не позволяет повторную итерацию или повторное прохождение было бы затратным (например, при чтении данных из базы данных или файла).

some(iterable $iterable, callable $predicate)bool

Проверяет, удовлетворяет ли хотя бы один элемент итератора условию, определенному в $predicate. Функция $predicate имеет сигнатуру function ($value, $key, iterable $iterable): bool и должна возвращать true хотя бы для одного элемента, чтобы метод some() вернул true.

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

Этот метод полезен для быстрой проверки, существует ли в коллекции хотя бы один элемент, удовлетворяющий определенному условию, например, содержит ли коллекция хотя бы одно четное число.

См. every().

toIterator(iterable $iterable): Iterator

Преобразует любой итерируемый объект (array, Traversable) в Iterator. Если входные данные уже являются Iterator, возвращает их без изменений.

$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Теперь у вас есть Iterator вместо массива

Этот метод полезен, когда нужно убедиться, что у вас есть Iterator, независимо от типа входных данных. Это может быть полезно при создании функций, которые работают с различными типами итерируемых данных.