Last active
July 5, 2022 08:40
-
-
Save teramako/579ca80c850a51e1516130ea5444e7fe to your computer and use it in GitHub Desktop.
Generatorの拡張
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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