javascriptfunctional-programminggenerator

Mapping a function on a generator in JavaScript


I have a generator called generateNumbers in JavaScript and another generator generateLargerNumbers which takes each value generated by generateNumbers and applies a function addOne to it, as such:

function addOne(value) {
  return value + 1
}

function* generateNumbers() {
  yield 1
  yield 2
  yield 3
}

function* generateLargerNumbers() {
  for (const number of generateNumbers()) {
    yield addOne(number)
  }
}

Is there any terser way to do this without building an array out of the generated values? I'm thinking something like:

function* generateLargerNumbers() {
  yield* generateNumbers().map(addOne) // obviously doesn't work
}

Solution

  • There isn't a built-in way to map over Generator objects, but you could roll your own function:

    const Generator = Object.getPrototypeOf(function* () {});
    Generator.prototype.map = function* (mapper, thisArg) {
      for (const val of this) {
        yield mapper.call(thisArg, val);
      }
    };
    

    Now you can do:

    function generateLargerNumbers() {
      return generateNumbers().map(addOne);
    }
    

    const Generator = Object.getPrototypeOf(function* () {});
    Generator.prototype.map = function* (mapper, thisArg) {
      for (const val of this) {
        yield mapper.call(thisArg, val);
      }
    };
    
    function addOne(value) {
      return value + 1
    }
    
    function* generateNumbers() {
      yield 1
      yield 2
      yield 3
    }
    
    function generateLargerNumbers() {
      return generateNumbers().map(addOne)
    }
    
    console.log(...generateLargerNumbers())