← Download MyJS

MyJS block

Ranges 1.0.0

Generate a range of numbers.

Download with this
Exports
range span
Works in
Browser and Node.js
The code of version 1.0.0
/**
 * Lazily generates numbers from `first` toward `last`, not including `last`.
 *
 * If `step` points away from `last`, nothing is generated. Because this is a
 * generator, errors are thrown when it is iterated, not when it is called.
 *
 * @function
 * @name range
 * @generator
 * @param {number} first - The first number to generate.
 * @param {number} last - The number to stop before. It is never generated.
 * @param {number} [step] - The amount to add each time. Defaults to `1`, or
 *   to `-1` when `first` is greater than `last`.
 * @yields {number} The next number in the range.
 * @returns {Generator.<number, void, undefined>} An iterator over the range.
 * @throws {Error} If `step` is `0`.
 * @throws {Error} If `step` is too small to change the current number, which
 *   can happen with very large numbers.
 * @example
 * [...range(0, 10, 3)]; // [0, 3, 6, 9]
 * [...range(5, 1)];     // [5, 4, 3, 2]
 * [...range(1, 5, -1)]; // []
 */

/**
 * Lazily generates numbers from `first` toward `last`, including `last` when
 * a step lands on it exactly.
 *
 * If `step` points away from `last`, nothing is generated. Because this is a
 * generator, errors are thrown when it is iterated, not when it is called.
 *
 * @function
 * @name span
 * @generator
 * @param {number} first - The first number to generate.
 * @param {number} last - The number to stop at. It is generated if a step
 *   lands on it exactly.
 * @param {number} [step] - The amount to add each time. Defaults to `1`, or
 *   to `-1` when `first` is greater than `last`.
 * @yields {number} The next number in the span.
 * @returns {Generator.<number, void, undefined>} An iterator over the span.
 * @throws {Error} If `step` is `0`.
 * @throws {Error} If `step` is too small to change the current number, which
 *   can happen with very large numbers.
 * @example
 * [...span(0, 10, 3)]; // [0, 3, 6, 9]
 * [...span(5, 1)];     // [5, 4, 3, 2, 1]
 * [...span(5, 5)];     // [5]
 */
var [range, span] = (partial => [partial(0, Math.ceil), partial(1, Math.floor)])(
  (offset, round) => function *(first, last, step) {
    if (step === 0) throw new RangeError('The step must not be 0.');
    step ??= first > last ? -1 : 1;
    if (first === last || (first < last) === (step > 0)) {
      let itersLeft = round((last - first) / step) + offset;
      for (let num = first; itersLeft-- > 0; num += step) {
        yield num;
        if (itersLeft > 0 && num + step === num) throw new RangeError('Next number cannot be calculated.');
      }
    }
  }
);

Versions

  1. 1.0.0 Oct 26, 2026

    Initial

JSDoc