发电机的过滤和映射功能

vit*_*y-t 6 javascript generator

JavaScript 中推荐的传递包含过滤+映射逻辑的生成器的方法是什么?

不知何故,JavaScript 生成器缺少诸如filtermap操作数之类的基本内容(类似于数组),以便能够创建包含该逻辑的生成器,而无需先运行迭代。

我的直接方法是实现应用逻辑的自定义函数:

function * filter(g, cb) {
    let a;
    do {
        a = g.next();
        if (!a.done && cb(a.value)) {
            yield a.value;
        }
    } while (!a.done);
    return a.value;
}

function * map(g, cb) {
    let a;
    do {
        a = g.next();
        if (!a.done) {
            yield cb(a.value);
        }
    } while (!a.done);
    return a.value;
}
Run Code Online (Sandbox Code Playgroud)

但这会造成回调地狱。我想简单地链接一个生成器,就像一个常规数组一样:

// create a filtered & re-mapped generator, without running it:
const gen = myGenerator().filter(a => a > 0).map(b => ({value: b})); 

// pass generator into a function that will run it:
processGenerator(gen);
Run Code Online (Sandbox Code Playgroud)

有没有办法扩展生成器以自动访问这些基本功能?

另外,如果有人想了解为什么这些基本的东西不是生成器实现的一部分,那就太棒了!我认为过滤和映射是序列所需的两个最重要的东西。

更新

这一切都以我编写自己的iter-ops库结束:)

Oli*_*ssé 5

您的解决方案的替代方案是使用循环for...of而不是do...while.

我还希望filtermap函数能够使用并生成如下所示的生成器函数:

function filter(gen, predicate) {
  return function*() {
    for (let e of gen()) {
       if (predicate(e)) {
         yield e; 
       }
     }
  }
}

function map(gen, fn) {
  return function*() {
    for (let e of gen()) {
      yield fn(e);
    }
  }
}

function generatorWrapper(gen) {
  return {
    call: () => gen(),
    filter: predicate => generatorWrapper(filter(gen, predicate)),
    map: fn => generatorWrapper(map(gen, fn))
  };
}

function* generator() {
  yield 1;
  yield 2;
  yield 3;
}

const it = generatorWrapper(generator)
  .filter(x => x > 1)
  .map(x => x * 2)
  .call();

for (let e of it) {
  console.log(e);
}
Run Code Online (Sandbox Code Playgroud)