Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ChunkedIteratorAggregate
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
2 / 2
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIterator
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of php-fast-forward/iterators.
7 *
8 * This source file is subject to the license that is bundled
9 * with this source code in the file LICENSE.
10 *
11 * @copyright Copyright (c) 2025-2026 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
12 * @license   https://opensource.org/licenses/MIT MIT License
13 *
14 * @see       https://github.com/php-fast-forward/iterators
15 * @see       https://github.com/php-fast-forward
16 * @see       https://datatracker.ietf.org/doc/html/rfc2119
17 */
18
19namespace FastForward\Iterator;
20
21use Traversable;
22
23/**
24 * Splits an iterable into fixed-size chunks.
25 *
26 * This iterator wraps a `Traversable` and groups elements into subarrays
27 * of a fixed size. If the total number of elements is not a multiple of
28 * the chunk size, the last chunk may contain fewer elements.
29 *
30 * ## Usage Example:
31 *
32 * @example Using ChunkedIteratorAggregate
33 * ```php
34 * use FastForward\Iterator\ChunkedIteratorAggregate;
35 *
36 * $chunks = new ChunkedIteratorAggregate(range(1, 10), 3);
37 *
38 * foreach ($chunks as $chunk) {
39 *     print_r($chunk);
40 * }
41 * // Outputs:
42 * // [1, 2, 3]
43 * // [4, 5, 6]
44 * // [7, 8, 9]
45 * // [10]
46 * ```
47 *
48 * @since 1.0.0
49 */
50class ChunkedIteratorAggregate extends CountableIteratorAggregate
51{
52    /**
53     * @var int the size of each chunk
54     */
55    private  int $chunkSize;
56
57    /**
58     * Initializes the ChunkedIteratorAggregate.
59     *
60     * @param iterable $iterator the iterator containing values to be chunked
61     * @param int $chunkSize the number of elements per chunk (must be >= 1)
62     */
63    public function __construct(
64        private  iterable $iterator,
65        int $chunkSize
66    ) {
67        $this->chunkSize = max(1, $chunkSize);
68    }
69
70    /**
71     * Retrieves an iterator that yields arrays containing elements in chunks.
72     *
73     * The iteration groups elements from the original iterator into
74     * subarrays of `$chunkSize` elements each.
75     *
76     * @return Traversable<int, array<int, mixed>> the iterator yielding chunked arrays
77     */
78    public function getIterator(): Traversable
79    {
80        $buffer = [];
81
82        foreach ($this->iterator as $value) {
83            $buffer[] = $value;
84
85            if (\count($buffer) === $this->chunkSize) {
86                yield $buffer;
87                $buffer = [];
88            }
89        }
90
91        if ([] !== $buffer) {
92            yield $buffer;
93        }
94    }
95}