Skip to documentation

Use Cases

This page shows complete scenarios rather than isolated API calls. Read it when you already know the class names but still want help translating them into a real workflow.

Batch records before writing to an external API

Use ChunkedIteratorAggregate when the receiving system expects fixed-size payloads:

use FastForward\Iterator\ChunkedIteratorAggregate;

$records = range(1, 7);

foreach (new ChunkedIteratorAggregate($records, 3) as $batch) {
    // Send one request per batch.
    print_r($batch);
}

Expected output:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 4
    [1] => 5
    [2] => 6
)
Array
(
    [0] => 7
)

Calculate moving comparisons

Use SlidingWindowIteratorIterator when each result needs to overlap with the previous one:

use FastForward\Iterator\SlidingWindowIteratorIterator;

$measurements = [10, 12, 13, 18, 21];

foreach (new SlidingWindowIteratorIterator($measurements, 3) as $window) {
    echo json_encode($window) . PHP_EOL;
}

Expected output:

[10,12,13]
[12,13,18]
[13,18,21]

Clean and deduplicate imported strings

You can compose iterators when the problem has more than one step:

use FastForward\Iterator\TrimIteratorIterator;
use FastForward\Iterator\UniqueIteratorIterator;

$rawTags = ['  PHP  ', 'php', ' Fast Forward ', 'PHP', 'fast forward'];

$trimmed = new TrimIteratorIterator($rawTags);
$unique = new UniqueIteratorIterator($trimmed, true, false);

foreach ($unique as $tag) {
    echo $tag . PHP_EOL;
}

Expected output:

PHP
Fast Forward

Understand grouping choices

ConsecutiveGroupIterator and GroupByIteratorIterator solve related but different problems:

use FastForward\Iterator\ConsecutiveGroupIterator;
use FastForward\Iterator\GroupByIteratorIterator;

$values = [1, 1, 2, 2, 1];

$consecutive = new ConsecutiveGroupIterator(
    $values,
    static fn(int $previous, int $current): bool => $previous === $current
);

$grouped = new GroupByIteratorIterator(
    $values,
    static fn(int $value): int => $value
);

print_r(iterator_to_array($consecutive, false));
print_r(iterator_to_array($grouped));

Expected output:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 1
        )
    [1] => Array
        (
            [0] => 2
            [1] => 2
        )
    [2] => Array
        (
            [0] => 1
        )
)
Array
(
    [1] => Array
        (
            [0] => 1
            [1] => 1
            [2] => 1
        )
    [2] => Array
        (
            [0] => 2
            [1] => 2
        )
)

Combine multiple sources deliberately

These three classes are easy to confuse, so it helps to see them side by side:

use FastForward\Iterator\ChainIterableIterator;
use FastForward\Iterator\InterleaveIteratorIterator;
use FastForward\Iterator\ZipIteratorIterator;

$left = ['A', 'B', 'C'];
$right = [1, 2];

echo json_encode(iterator_to_array(new ChainIterableIterator($left, $right), false)) . PHP_EOL;
echo json_encode(iterator_to_array(new InterleaveIteratorIterator($left, $right), false)) . PHP_EOL;
echo json_encode(iterator_to_array(new ZipIteratorIterator($left, $right), false)) . PHP_EOL;

Expected output:

["A","B","C",1,2]
["A",1,"B",2,"C"]
[["A",1],["B",2]]

Reuse an expensive generator

Plain generators are single-pass. Reach for GeneratorRewindableIterator or GeneratorCachingIteratorAggregate when you need more than one iteration:

use FastForward\Iterator\GeneratorRewindableIterator;

$source = new GeneratorRewindableIterator((function (): Generator {
    yield 'first';
    yield 'second';
})());

echo json_encode(iterator_to_array($source, false)) . PHP_EOL;
echo json_encode(iterator_to_array($source, false)) . PHP_EOL;

Expected output:

["first","second"]
["first","second"]

Inspect upcoming and previous values

LookaheadIterator is helpful when parsing token-like streams or building state machines:

use FastForward\Iterator\LookaheadIterator;

$iterator = new LookaheadIterator(['A', 'B', 'C']);

foreach ($iterator as $value) {
    echo $value
        . ' | next=' . json_encode($iterator->lookAhead())
        . ' | prev=' . json_encode($iterator->lookBehind())
        . PHP_EOL;
}

Expected output:

A | next="B" | prev=null
B | next="C" | prev="A"
C | next=null | prev="B"

Filter a directory by extension

Use FileExtensionFilterIterator when you already have a filesystem iterator and only want specific file types:

use FastForward\Iterator\FileExtensionFilterIterator;

$files = new FileExtensionFilterIterator(
    new FilesystemIterator(__DIR__),
    'php',
    'rst'
);

foreach ($files as $file) {
    echo $file->getFilename() . PHP_EOL;
}

See the examples directory for more package-specific demonstrations.

Search results