Skip to content

Instantly share code, notes, and snippets.

@DanCouper
Last active January 4, 2024 12:47
Show Gist options
  • Save DanCouper/c56992662c3582877092ab77c42fef7d to your computer and use it in GitHub Desktop.
Save DanCouper/c56992662c3582877092ab77c42fef7d to your computer and use it in GitHub Desktop.
/**
* @typedef {Object} RangeOpts
* @property {number} [step=1]
* @property {boolean} [isInclusive=2]
*/
class Range {
#index = 0;
#length = 0;
/**
* @param {number} start
* @param {number} end
* @param {RangeOpts} options
*/
constructor(start, end, { step = 1, isInclusive = true } = {}) {
switch (true) {
case !Number.isInteger(step) || step === 0: throw new RangeError("step value must be a non-zero positive or negative integer");
case start < end && Math.sign(step) === -1: throw new RangeError("step value must be positive for an ascending range");
case start > end && Math.sign(step) === +1: throw new RangeError("step value must be negative for a descending range");
}
this.start = start;
this.end = end;
this.step = step;
this.isIncusive = isInclusive;
this.#length = Math.ceil((this.end - this.start) / this.step) + Number(this.isInclusive);
}
[Symbol.iterator]() {
return this;
}
next() {
if (this.#index === this.#length) return { done: true };
const value = this.#index * this.step + this.start;
this.#index++;
return { value, done: false };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment