Skip to content

Instantly share code, notes, and snippets.

@alanrsoares
Last active April 15, 2016 05:34
Show Gist options
  • Save alanrsoares/40eb46559084dcc565f26ffc994c8883 to your computer and use it in GitHub Desktop.
Save alanrsoares/40eb46559084dcc565f26ffc994c8883 to your computer and use it in GitHub Desktop.
Lazy range implementation with Symbol.iterator - live demo => http://jsbin.com/jeguzo/edit?js,console
// Practical Application of a Symbol.iterator
// to build a Lazy Sequence
const asc = xs => xs.sort((a, b) => a - b)
class Range {
constructor(to, from = 0, step = 1) {
this.step = step
if (typeof to === 'undefined' || to === null) {
this.infinite = true
this._from = from
} else {
let [f, t] = asc([from, to])
this._from = f
this._to = t
}
}
from (n) {
this._from = n
return this
}
to (n) {
this._to = n
this.infinite = false
return this
}
* [Symbol.iterator] () {
let current = this._from
const keepGoing = () => this.infinite || current <= this._to
while (keepGoing()) {
yield current
current += this.step
}
}
toArray () {
return Array.from(this)
}
}
// static `factory` helper
const range = (...args) => new Range(...args)
// tests
console.clear()
console.log(range(10, 20))
console.log(range(10, 20, 3))
console.log(range().from(1000))
const s1 = range().to(20).from(10)
console.log(s1.toArray())
console.log(range().toArray().length) //=> long random number above 50k
// Lazily logs numbers from 10 to 20
for (let i of range(10, 20)) {
console.log(i)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment