Search code examples
javascriptpythoniteratorgenerator

Is there any way to create python-like generators in javascript?


In python if you loop over (or consume) an

  1. iterator
  2. function return value

you do not even know which one you have. So it does not matter from the caller side if you have returned or yielded values from the callee to use in caller.

However, as far as I know in javascript if you want to use yield, you have to explicitly mark the function* with an asterisk and can not treat the computed value the same way as a "regular function's return value" on the caller side.

Is there an abstraction in javascript to hide these differences to get the same nice abstraction which python has?


Solution

  • There are several constructs in JavaScript where the caller does not need to know whether the called function is a generator, or a plain function that returns an array, string, Map, ...etc. These return values all have in common that they are iterable.

    Here are two examples on how you can treat the return value of such a function:

    1. Iterate through the values:

      for (let x of f()) {
          // ...
      }
      

      Depending on what f() returns, x will be the following:

      • Iterate a string: get each character
      • Iterate an array: get each element of it
      • Iterate a Map: get each key/value pair of it
      • Iterate an iterator (maybe returned by a generator): get each yielded value from it
      • ...
    2. Create an array from the values:

      const copy = Array.from(f());
      

      Or also:

      const copy = [...f()];
      

      NB: the nice thing of Array.from is that it accepts a callback function as a second argument: a mapper called for each value.

    3. Spread the values as arguments to another function

      If the values are numerical:

      Math.min(...f());
      

      As Math.min can accept multiple arguments (not just two), this gives the minimum value of the whole series (as min does in Python).

    Read more about iterators and iterables on MDN