javascriptecmascript-6generator

How can I consume an iterable in batches (equally sized chunks)?


I am often using batch() in Python. Is there some alternative in JavaScript since ES6 which has iterators and generator functions?


Solution

  • I had to write one for myself, which I'm sharing here for me and the others to find here easily:

    // subsequently yield iterators of given `size`
    // these have to be fully consumed
    function* batches(iterable, size) {
      const it = iterable[Symbol.iterator]();
      while (true) {
        // this is for the case when batch ends at the end of iterable
        // (we don't want to yield empty batch)
        let {value, done} = it.next();
        if (done) return value;
    
        yield function*() {
          yield value;
          for (let curr = 1; curr < size; curr++) {
            ({value, done} = it.next());
            if (done) return;
    
            yield value;
          }
        }();
        if (done) return value;
      }
    }
    

    It yields generators, not Arrays for example. You have to fully consume each batch before calling next() on it again.