I built this very-basic lazy list (I'll add more methods as I need them). You provide it an array, a generator or any iterator. It creates a lazy list, which lets you run a pipeline of transformations in a lazy manner, meaning that they'll only be applied as you pull values out of the list.
Here's the class:
class List {
static range(start, end) {
return new List(function* () {
while (start <= end) {
yield start++;
}
});
}
constructor(source) {
if (typeof source == 'function') {
this.generator = source;
} else {
this.generator = function* () {
yield* source;
};
}
}
filter(predicate) {
return new List(function* () {
for (const item of this) {
if (predicate(item)) {
yield item;
}
}
}.bind(this));
}
map(mapper) {
return new List(function* () {
for (const item of this) {
yield mapper(item);
}
}.bind(this));
}
take(size) {
return new List(function* () {
for (const item of this) {
if (size--) {
yield item;
} else {
break;
}
}
}.bind(this));
}
*[Symbol.iterator] () {
yield* this.generator();
}
toArray() {
return [...this];
}
}
Here's a simple example of how to use it:
List.range(1, 10 ** 9)
.filter(number => number % 10 == 0)
.map(number => 'Item ' + number)
.take(5)
.toArray();
Trying the same with a regular array:
Array.from({ length: 10 ** 9 }, (v, i) => i + 1)
.filter(number => number % 10 == 0)
.map(number => 'Item ' + number)
.slice(0, 5);
...will run out of memory before it completes.
cons
itself ((:)
in Haskell). Though can be implemented with a function each time, it probably makes sense to make it specific. \$\endgroup\$ – bipll Mar 23 '18 at 12:42return new List(function* ()
code can be reduced. One could probably dynamically definefilter
,map
,take
from an array of the inner generator functions. Not sure if this is clean, though, and one loses all the typings (when using TypeScript). \$\endgroup\$ – ComFreek Mar 23 '18 at 12:48yield
, and the only way to do that is within a generator function. Also, I'm not sure what you mean by "One could probably dynamically definefilter
,map
,take
from an array of the inner generator functions". There's no array, which is the whole point here. The values are all flowing down one by one. \$\endgroup\$ – Joseph Silber Mar 23 '18 at 12:50