Skip to content

Instantly share code, notes, and snippets.

@teramako
Last active July 5, 2022 08:40
Show Gist options
  • Save teramako/579ca80c850a51e1516130ea5444e7fe to your computer and use it in GitHub Desktop.
Save teramako/579ca80c850a51e1516130ea5444e7fe to your computer and use it in GitHub Desktop.
Generatorの拡張
const iter = (function(){
// 元のGenerator.prototype
const GeneratorProto = ({*g(){}}).g().constructor.prototype;
// 拡張してmap,filterを付与したprototype
const ExtendedGeneratorProto = Object.setPrototypeOf({
map (func, thisArg = null) {
const iterable = this;
return Object.setPrototypeOf(function*() {
var i = 0;
for (const item of iterable) {
// console.log("iterMap", item, i);
yield func.call(thisArg, item, i);
i++;
}
}(), ExtendedGeneratorProto);
},
filter (func, thisArg = null) {
const iterable = this;
return Object.setPrototypeOf(function*(){
var i = 0;
for (const item of iterable) {
// console.log("iterFilter", item, i);
if (func.call(thisArg, item, i)) yield item;
i++;
}
}(), ExtendedGeneratorProto);
},
uniq(){
const iterable = this;
return Object.setPrototypeOf(function*(){
var s = new Set();
for (const item of iterable) {
if (!s.has(item)) {
yield item;
s.add(item);
}
}
}(), ExtendedGeneratorProto);
},
flat() {
const iterable = this;
return Object.setPrototypeOf(function*(){
for (const item of iterable) {
if (typeof item === "string") yield item;
else if (Symbol.iterator in item) yield* item;
else yield item;
}
}(), ExtendedGeneratorProto);
}
}, GeneratorProto);
return iterable => {
return Object.setPrototypeOf(function*() {
yield* iterable;
}(), ExtendedGeneratorProto);
};
}());
// Sample
function* range(start, end, step = 1) {
for (var i = start; i <= end; i+=step) {
yield i;
}
}
[...iter(range(1, 5)).filter(i => i%2 == 1).map(i => i ** i)]
// => [1, 27, 3125]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment