Skip to content

Instantly share code, notes, and snippets.

@teramako
Last active September 18, 2016 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teramako/3eaa5692daea5cf3b81dff121daa2d78 to your computer and use it in GitHub Desktop.
Save teramako/3eaa5692daea5cf3b81dff121daa2d78 to your computer and use it in GitHub Desktop.
Generatorのプロトタイプ拡張。ま、やっつけです。
/* Usage
function * gene() {
console.log("iter");
yield 1;
console.log("iter");
yield 2;
console.log("iter");
yield 3;
}
var result = gene
.filter(num => {
console.log("filter: ", num);
return num % 2 === 1;
})
.map(num => {
console.log("map: ", num);
return num + 10;
});
console.log("result: ", [...result])
*/
{
let g = function*(){};
let GeneratorFunctionPrototype = g.constructor.prototype;
let GeneratorPrototype = GeneratorFunctionPrototype.prototype;
function reduceIter(iter, func, initValue) {
let result = initValue, done, value;
if (result === undefined) {
let {done,value} = iter.next();
if (done) return;
result = value;
}
while({done, value} = iter.next(), !done) {
result = func(result, value);
}
return result;
}
function * mapIter(iter, func) {
let i = 0;
for (let item of iter) {
yield func(item, i);
++i;
}
}
function * filterIter(iter, func) {
let i = 0;
for (let item of iter) {
if (func(item, i)) yield item;
++i;
}
}
function forEachIter(iter, func) {
let i = 0;
for (let item of iter) {
func(item, i);
}
}
Object.defineProperties(GeneratorFunctionPrototype, {
reduce: {
writable: true, configurable: true,
value: function reduce (func, initValue) { return reduceIter(this(), func, initValue); }
},
map: {
writable: true, configurable: true,
* value(func) { yield * mapIter(this(), func); }
},
filter: {
writable: true, configurable: true,
* value(func) { yield * filterIter(this(), func); }
},
forEach: {
writable: true, configurable: true,
value(func) { forEachIter(this(), func); }
}
});
Object.defineProperties(GeneratorPrototype, {
reduce: {
writable: true, configurable: true,
value(func, initValue) { return reduceIter(this, func, initValue); }
},
map: {
writable: true, configurable: true,
* value(func) { yield * mapIter(this, func); }
},
filter: {
writable: true, configurable: true,
* value(func) { yield * filterIter(this, func); }
},
forEach: {
writable: true, configurable: true,
value(func) { forEachIter(this, func); }
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment