UNPKG

iteragain

Version:

Javascript Iterable/Iterator/Generator-function utilities.

79 lines 2.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RangeIterator = void 0; const toArray_1 = require("../toArray"); /** * A class for representing a range of numbers and also iterating through them. When `next.done` is true, resets the * internal counter back to `start`. */ class RangeIterator { constructor(...params) { /** Alias of `includes`. */ this.has = this.includes; /** Alias of `nth`. */ this.at = this.nth; let start = 0, stop = 0; let step; if (params.length === 1) stop = params[0]; else if (params.length > 1) [start, stop, step] = params; if (typeof step !== 'number') step = Math.sign(stop - start); const stepSign = Math.sign(step); if (stepSign === 0) this.next = () => ({ done: true, value: undefined }); this.start = this.i = start; this.stop = stop; this.step = step; this.stepSign = stepSign; // If the start is not in this range, then it's 0, otherwise calc normally. this._length = this.includes(start) ? Math.abs(Math.ceil((stop - start) / step)) : 0; } /** The length of this range of numbers. */ get length() { return this._length; } [Symbol.iterator]() { return this; } next() { if (Math.sign(this.stop - this.i) !== this.stepSign) { this.i = this.start; return { done: true, value: undefined }; } const value = this.i; this.i += this.step; return { done: false, value }; } /** Returns true if `n` is inside of this range. */ includes(n) { if ((n - this.start) % this.step !== 0) return false; return this.stepSign > 0 ? n >= this.start && n < this.stop : n <= this.start && n > this.stop; } /** Returns the number at `index` in this range. `index` can be negative to access indices starting from the end. */ nth(index) { const num = index >= 0 ? this.start + index * this.step : this.stop + index * this.step; return this.includes(num) ? num : undefined; } /** Returns the index that `n` is at in this range. */ index(n) { return (n - this.start) / this.step; } /** Returns true if this range is equal to another. */ equal(other) { return this.start === other.start && this.stop === other.stop && this.step === other.step; } // slice(start: number, end?: number) {} toString() { return `range(${this.start}, ${this.stop}, ${this.step})`; } /** Iterates and collects all values into an Array. */ toArray() { return (0, toArray_1.default)(this); } } exports.RangeIterator = RangeIterator; exports.default = RangeIterator; //# sourceMappingURL=RangeIterator.js.map