Last active
September 19, 2020 22:40
-
-
Save friendlyanon/f97fa04b2b994bd99279d785a8ca648b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function* range(start, endExclusive, step) { | |
switch (arguments.length) { | |
case 1: | |
endExclusive = start; | |
start = 0; | |
case 2: | |
step = start > endExclusive ? -1 : 1; | |
} | |
if (start === endExclusive) { | |
return; | |
} | |
const predicate = step > 0 ? (x, y) => x < y : (x, y) => x > y; | |
for (; predicate(start, endExclusive); start += step) { | |
yield start; | |
} | |
} | |
export class Range { | |
constructor(start, endExclusive, step) { | |
switch (arguments.length) { | |
case 1: | |
endExclusive = start; | |
start = 0; | |
case 2: | |
step = start > endExclusive ? -1 : 1; | |
} | |
this._current = start; | |
this._start = start; | |
this._endExclusive = endExclusive; | |
this._step = step; | |
this._predicate = step > 0 | |
? (x, y) => x < y | |
: (x, y) => x > y; | |
} | |
get start() { | |
return this._start; | |
} | |
get endExclusive() { | |
return this._endExclusive; | |
} | |
get step() { | |
return this._step; | |
} | |
/** | |
* This is used if the range is going in the negative direction, e.g. [0, -5) | |
*/ | |
_includesNegative(number) { | |
return this._start >= number && number > this._endExclusive; | |
} | |
/** | |
* This is used if the range is going in the positive direction, e.g. [0, 5) | |
*/ | |
_includesPositive(number) { | |
return this._start <= number && number < this._endExclusive; | |
} | |
includes(number) { | |
return this._start < this._endExclusive | |
? this._includesPositive(number) | |
: this._includesNegative(number); | |
} | |
next() { | |
if (!this._predicate(this._current, this._endExclusive)) { | |
return { done: true, value: void 0 }; | |
} | |
const value = this._current; | |
this._current += this._step; | |
return { done: false, value }; | |
} | |
[Symbol.iterator]() { | |
return this; | |
} | |
toArray() { | |
return Array.from(this); | |
} | |
toJSON() { | |
return JSON.stringify(this.toArray()); | |
} | |
static of(start, endExclusive, step) { | |
return new Range(start, endExclusive, step); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment