javascript - 生成器的过滤器和映射函数

标签 javascript generator

在 JavaScript 中传递包含过滤 + 映射逻辑的生成器的推荐方法是什么?
不知何故,JavaScript 生成器缺少诸如 filter 之类的基本内容。和 map操作数,类似于数组,能够创建包含该逻辑的生成器,而无需先运行迭代。
我的正面方法是实现应用逻辑的自定义函数:

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;
}
但这会造成回调 hell 。我想简单地链接一个生成器,就像一个常规数组:
// 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);
有没有办法扩展生成器以自动访问这些基本功能?
另外,如果有人想强调为什么这些基本的东西不是生成器实现的一部分,那就太棒了!我认为过滤和映射是序列需要的两个最基本的东西。

最佳答案

您的解决方案的替代方法是使用 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);
}

关于javascript - 生成器的过滤器和映射函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68238061/

相关文章:

javascript - JQuery 访问单击的元素而不使用闭包

javascript - 无法将数组插入数组(制作数组的数组)

javascript - React 中的受控组件与非受控组件

swift - X、Y 坐标的随机数生成器

javascript - 如何结合 ES6 Generators 和 Promises

typescript - 为什么 TypeScript 的 IterableIterator<> 和 Generator<> 泛型略有不同?

python - 将生成器分配给字典直接抛出 StopIteration

javascript - 取消选中 angularjs 中的复选框

javascript - 如何使用 Cypress stub 模块功能?

javascript - 如果调用了 .bind() 函数,是否无法判断函数是否为生成器函数?