Skip to content

Instantly share code, notes, and snippets.

@emctague
Last active February 3, 2021 14:50
Show Gist options
  • Save emctague/0d58d2df005074b105dcf1e71425d3ef to your computer and use it in GitHub Desktop.
Save emctague/0d58d2df005074b105dcf1e71425d3ef to your computer and use it in GitHub Desktop.
JavaScript Generator Utility Functions

This source file modifies the prototype of Generator Function objects to provide the following functions already available to arrays, allowing them to operate on demand on generators:

  • map

  • reduce

  • join

  • forEach

  • concat

  • entries

  • every

  • fill

  • filter

  • find

  • push

  • some

It also provides a range(start, end) generator function.

Note that unlike the original Array functions, there is no thisArg accepted, and callback functions will not receive a reference to the existing array as there is no array, only a generator.

const GenConstructor = (function*(){}()).constructor;
GenConstructor.prototype.map = function*(alt) {
let i = 0;
for (let v of this) {
yield alt(v, i++);
}
}
GenConstructor.prototype.reduce = function(reducer, initialValue) {
let i = 0;
if (initialValue === undefined) {
initialValue = this.next().value;
i += 1;
}
for (let v of this) {
initialValue = reducer(initialValue, v, i++);
}
return initialValue;
}
GenConstructor.prototype.join = function(joiner) {
return this.reduce((a, b) => a.toString() + joiner + b.toString());
}
GenConstructor.prototype.forEach = function(looper) {
let i = 0;
for (let v of this) {
looper(v, i++);
}
}
function* range(a, b) {
for (let v = a; v <= b; v++) {
yield v;
}
}
GenConstructor.prototype.concat = function*(other) {
yield* this;
yield* other;
}
GenConstructor.prototype.entries = function*() {
yield* this.map((a, i) => [i, a]);
}
GenConstructor.prototype.every = function(test) {
let i = 0;
for (let v of this) {
if (!test(v, i++)) return false;
}
return true;
}
GenConstructor.prototype.fill = function*(value, start, end) {
yield* this.map((a, i) => ((start === undefined || i >= start) && (end === undefined || i <= end)) ? value : a);
}
GenConstructor.prototype.filter = function*(callback) {
let i = 0;
for (let v of this) {
if (callback(v, i++)) yield v;
}
}
GenConstructor.prototype.find = function(callback) {
return this.filter(callback).next().value;
}
GenConstructor.prototype.push = function() {
yield* this;
yield* arguments;
}
GenConstructor.prototype.some = function(test) {
return this.every((a, i) => !test(a, i));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment