Using JavaScript generator functions for ranges

JavaScript, Function, Array · Jun 12, 2021

JavaScript ES6 generators allow you to define functions that can be exited and later re-entered, while retaining their context (variable bindings). They are defined using function* (function keyword followed by an asterisk) and use yield expressions to return their result. For example:

function* generateRange(end, start = 0, step = 1) {
  let x = start - step;
  while(x < end - step) yield x += step;
}

const gen5 = generateRange(5);
let x = gen5.next();

while (!x.done) {
  console.log(x.value);
  x = gen5.next();
} // Logs: 0, 1, 2, 3, 4

In the above example, we define a generator function, generateRange, which will return each value between start and end, incrementing by step each time. We use the generator object to call Generator.prototype.next() until it returns {value: undefined, done: true} to iterate over the values the generator produces.

Symbol.iterator specifies the default iterator for an object. Oftentimes, Symbol.iterator is implemented using a generator function. For example:

const iterableXx = {
  [Symbol.iterator]: function* () {
    yield 1;
    yield 2;
  }
};

console.log([...iterableX]); // [1, 2]

As you can see in this example, the object is made iterable by assigning a generator function to its Symbol.iterator property. This can come especially handy, if you want to iterate over some arbitrary data or create an object that is iterable and uses a generator function under the hood.

Knowing how both concepts work, we can combine them to create a range generator, similar to Python or Ruby's ranges:

const range = (end, start = 0, step = 1) => {
  function* generateRange() {
    let x = start - step;
    while(x < end - step) yield x += step;
  }
  return {
    [Symbol.iterator]: generateRange
  };
}

console.log([...range(7)]); // [0, 1, 2, 3, 4, 5, 6]
for (let i of range(8, 2, 2)) console.log(i); // Logs: 2, 4, 6

Written by Angelos Chalaris

I'm Angelos Chalaris, a JavaScript software engineer, based in Athens, Greece. The best snippets from my coding adventures are published here to help others learn to code.

If you want to keep in touch, follow me on GitHub.

More like this

  • JavaScript Arrays

    Master array manipulation in JavaScript with this ES6 snippet collection.

    Collection · 210 snippets

  • Range generator

    Creates a generator, that generates all values in the given range using the given step.

    JavaScript, Function · Oct 11, 2020

  • Introduction to arrow functions in JavaScript

    JavaScript arrow functions are a very useful tool to learn and master. Here's a complete introduction to everything you need to know.

    JavaScript, Function · Jun 12, 2021

  • Using random values with pure functions

    Randomness and pure functions don't seem to go hand in hand. But where there's a will, there's a way.

    JavaScript, Function · Jun 19, 2022