forked from davidflanagan/jstdg7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Range.js
42 lines (37 loc) · 1.84 KB
/
Range.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
* A Range object represents a range of numbers {x: from <= x <= to}
* Range defines a has() method for testing whether a given number is a member
* of the range. Range is iterable and iterates all integers within the range.
*/
class Range {
constructor (from, to) {
this.from = from;
this.to = to;
}
// Make a Range act like a Set of numbers
has(x) { return typeof x === "number" && this.from <= x && x <= this.to; }
// Return string representation of the range using set notation
toString() { return `{ x | ${this.from} ≤ x ≤ ${this.to} }`; }
// Make a Range iterable by returning an iterator object.
// Note that the name of this method is a special symbol, not a string.
[Symbol.iterator]() {
// Each iterator instance must iterate the range independently of
// others. So we need a state variable to track our location in the
// iteration. We start at the first integer >= from.
let next = Math.ceil(this.from); // This is the next value we return
let last = this.to; // We won't return anything > this
return { // This is the iterator object
// This next() method is what makes this an iterator object.
// It must return an iterator result object.
next() {
return (next <= last) // If we haven't returned last value yet
? { value: next++ } // return next value and increment it
: { done: true }; // otherwise indicate that we're done.
},
// As a convenience, we make the iterator itself iterable.
[Symbol.iterator]() { return this; }
};
}
}
for(let x of new Range(1,10)) console.log(x); // Logs numbers 1 to 10
[...new Range(-2,2)] // => [-2, -1, 0, 1, 2]