Отображение функции на генераторе в JavaScript
У меня есть генератор с именем generateNumbers
в JavaScript и еще один генератор generateLargerNumbers
, который принимает каждое значение, сгенерированное с помощью generateNumbers
, и применяет к нему функцию addOne
, как таковую:
function addOne(value) {
return value + 1
}
function* generateNumbers() {
yield 1
yield 2
yield 3
}
function* generateLargerNumbers() {
for (const number of generateNumbers()) {
yield addOne(number)
}
}
Есть ли способ сделать это без создания массива из сгенерированных значений? Я думаю что-то вроде:
function* generateLargerNumbers() {
yield* generateNumbers().map(addOne) // obviously doesn't work
}
Ответы
Ответ 1
Нет встроенного способа сопоставления объектов Generator
, но вы можете свернуть свою собственную функцию:
const Generator = Object.getPrototypeOf(function* () {});
Generator.prototype.map = function* (mapper, thisArg) {
for (const val of this) {
yield mapper.call(thisArg, val);
}
};
Теперь вы можете сделать:
function generateLargerNumbers() {
return generateNumbers().map(addOne);
}
const Generator = Object.getPrototypeOf(function* () {});
Generator.prototype.map = function* (mapper, thisArg) {
for (const val of this) {
yield mapper.call(thisArg, val);
}
};
function addOne(value) {
return value + 1
}
function* generateNumbers() {
yield 1
yield 2
yield 3
}
function generateLargerNumbers() {
return generateNumbers().map(addOne)
}
console.log(...generateLargerNumbers())
Ответ 2
генераторы более высокого порядка
Вы можете сами управлять функциями генератора
const Generator =
{
map: (f,g) => function* (...args)
{
for (const x of g (...args))
yield f (x)
},
filter: (f,g) => function* (...args)
{
for (const x of g (...args))
if (f (x))
yield x
}
}
// some functions !
const square = x =>
x * x
const isEven = x =>
(x & 1) === 0
// a generator !
const range = function* (x = 0, y = 1)
{
while (x < y)
yield x++
}
// higher order generator !
for (const x of Generator.map (square, Generator.filter (isEven, range)) (0,10))
console.log('evens squared', x)
Ответ 3
Как о создании объекта итератора вместо использования вложенных генераторов?
function* generateNumbers(){
yield 1;
yield 2;
yield 3;
}
function generateGreaterNumbers(){
return { next(){ var r = this.gen.next(); r.value+=1; return r; }, gen: generateNumbers() };`
}