For AI agents: the complete documentation index is available at /tc39-atlas/en/llms.txt, the full documentation bundle is available at /tc39-atlas/en/llms-full.txt, and this page is available as Markdown at /tc39-atlas/en/proposals/proposal-iterator-chunking.md.
  • English
  • iterator chunking S3

    Proposal details
    Proposal overview

    This proposal adds chunks() and windows() methods to iterators for consuming streams in non-overlapping and overlapping subsequences of a given size. It includes comprehensive use cases, such as pagination, batch processing, and sliding window computations.

    Note

    The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.

    Iterator Chunking

    A TC39 proposal to consume an iterator as either overlapping or non-overlapping subsequences of configurable size.

    Stage: 3. Further advancement is dependent on 2 or more shipping implementations.

    Specification: https://tc39.es/proposal-iterator-chunking/

    presentations to committee

    motivation

    It can be useful to consume a stream by more than one value at a time. For example, certain algorithms require looking at adjacent elements.

    chunking

    This is commonly solved for non-overlapping subsequences with a "chunking" method that works like the following:

    const digits = () => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].values();
    
    let chunksOf2 = Array.from(digits().chunks(2));
    // [ [0, 1], [2, 3], [4, 5], [6, 7], [8, 9] ]
    
    let chunksOf3 = Array.from(digits().chunks(3));
    // [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [9] ]
    
    let chunksOf4 = Array.from(digits().chunks(4));
    // [ [0, 1, 2, 3], [4, 5, 6, 7], [8, 9] ]
    use cases for chunking
    • pagination
    • columnar/grid layouts, such as calendars
    • batch/stream processing
    • matrix operations
    • formatting/encoding
    • bucketing (using a computed chunk size, for iterators of known size)

    sliding window

    When overlapping sequences are needed, this is commonly called a "sliding window".

    let windowsOf2 = Array.from(digits().windows(2));
    // [ [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9] ]
    
    let windowsOf3 = Array.from(digits().windows(3));
    // [ [0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9] ]
    
    let windowsOf4 = Array.from(digits().windows(4));
    // [ [0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9] ]
    use cases for sliding windows
    • running/continuous computations, such as averages
    • context-sensitive algorithms, such as pairwise comparisons
    • carousels and their analogues (when applied to an infinite cycle)

    prior art

    other languages

    languagelibrarychunkswindowschunks of 0?truncates windows?
    C++std::ranges::viewschunkslideundefined behaviorno
    Clojurecorepartitionpartitioninfinite empty listswhen insufficient padding;
    terminates after 1
    ElmList.ExtragroupsOfgroupsOfWithStepempty listno
    HaskellsplitchunksOfdivvyinfinite empty listsyes
    JavaStreamGatherers.windowFixedGatherers.windowSlidingthrowsno, step not configurable
    KotlinIterablechunkedwindowedthrowsconfigurable via parameter
    .NETSystem.LinqEnumerable.Chunk--throwsN/A
    PHParrayarray_chunk--throwsN/A
    Pythonitertools (3.12)batched--??N/A
    Pythonmore-itertoolsgrouperwindowedempty iteratorno, mandatory fill value
    RubyEnumerableeach_sliceeach_consthrowsno, step not configurable
    RustIteratorarray_chunksmap_windowspanicsno, step not configurable
    Rustslicechunkswindowspanicsno, step not configurable
    ScalaSeqgroupedslidingthrowsyes
    SwiftSequence----N/AN/A

    JS libraries

    librarychunkswindowschunks of 0?truncates windows?
    chunkchunk--coerces 0 to false 😞N/A
    extra-iterablechunkchunkinfinite empty arraysyes
    iter-opspage--throwsN/A
    iter-toolsbatchwindow, windowAhead, windowBehindthrowsoptionally
    iterablefuchunk--collects everything into a single arrayN/A
    itertools-tschunkwisechunkwiseOverlapthrowsyes
    Lodash / Underscorechunk--infinite empty arraysN/A
    RamdasplitEveryapertureinfinite empty arraysno
    sequencychunk--throwsN/A
    wuchunk--collects everything into a single arrayN/A