A TC39 proposal to create iterators by sequencing existing iterators.
Stage: 4
Specification:https://tc39.es/proposal-iterator-sequencing/
Often you have 2 or more iterators, the values of which you would like to consume in sequence, as if they were a single iterator. Iterator libraries (and standard libraries of other languages) often have a function called concat or chain to do this. In JavaScript today, one can accomplish this with generators:
letlows=Iterator.from([0,1,2,3]);lethighs=Iterator.from([6,7,8,9]);letlowsAndHighs=function*(){yield*lows;yield*highs;}();Array.from(lowsAndHighs);// [0, 1, 2, 3, 6, 7, 8, 9]It is also useful to be able to sequence immediate values among the iterators, as one would do with yield using the generator approach.
letdigits=function*(){yield*lows;yield4;yield5;yield*highs;}();Array.from(digits);// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]We should explore how to make this more ergonomic and functional.
letdigits=Iterator.concat(lows,[4,5],highs);For the (rare) case of infinite iterators of iterators, use Iterator.prototype.flatMap with the identity function.
function*selfCountingSequenceHelper(){for(letn=1;;++n){yieldArray(n).fill(n);}}letselfCountingSequence=selfCountingSequenceHelper().flatMap(x=>x)| language | data type | exactly 2 | arbitrary |
|---|---|---|---|
| Clojure | lazy seq | concat | |
| Elm | List | append/++ | concat |
| Haskell | Semigroup | <> | mconcat |
| OCaml | Seq | append | concat |
| Python | iterator | chain | |
| Ruby | Enumerable | chain | |
| Rust | Iterator | chain | flatten |
| Scala | Iterator | concat/++ | |
| Swift | LazySequence | joined |
| library | exactly 2 | arbitrary |
|---|---|---|
| @softwareventures/iterator | prependOnce/appendOnce | concatOnce |
| extra-iterable | concat | |
| immutable.js | Seq::concat | |
| iterablefu | concatenate | |
| itertools-ts | chain | |
| lodash | flatten | |
| ramda | concat | unnest |
| sequency | plus | |
| wu | chain |