【问题标题】:filter values from a javascript generator-stream从 javascript 生成器流中过滤值
【发布时间】:2020-08-30 18:39:38
【问题描述】:

我最近看了这个interesting video on the computerphile 并决定使用 JavaScript 生成器来实现筛子算法。总的来说,我对 JavaScript 非常有信心,但之前从未直接使用过生成器。

这是我目前所拥有的:

function* nextNaturalNumber(n) {
    yield n;
    yield* nextNaturalNumber(n + 1);
}   

function* sieve(n) {
    let count = 0;
    let g = nextNaturalNumber(2);
    while (count++ < n) {
        const possiblePrime = g.next().value;
        yield possiblePrime;
        // here's where I'm stuck:
        // how can I filter the values from the nextNaturalNumber-generator stream that are not divisible by 2?
    }
}

// print the first 10 primes
for (const prime of sieve(10)) {
    console.log(prime);
}

正如代码评论中提到的,我一直坚持如何从生成器流中过滤不能被 2 整除的值,从而执行“筛子”操作。在 JavaScript 中是否有一种简单的方法来做到这一点(如在 Python 中使用yield from sieve(i for i in s if i%n !=0))?

【问题讨论】:

  • 在您的 python 代码中,您似乎将迭代器传递给sieve,而不是数字。您是否也尝试在 JS 中复制它?

标签: javascript generator


【解决方案1】:

不幸的是,Javascript 没有那么多好的迭代器操作。但是,您可以只创建一个过滤器函数,循环遍历迭代器并生成匹配的值:

function* nextNaturalNumber(n) {
    // switch to iterative to avoid stack overflows
    while(true) {
        yield n;
        n ++;
    }
}   

function* filterIter(iter, pred) {
    for (const item of iter) {
        if (pred(item)) {
            yield item;
        }
    }
}

function* sieve(n) {
    let count = 0;
    let g = nextNaturalNumber(2);
    while (count++ < n) {
        const possiblePrime = g.next().value;
        yield possiblePrime;
        g = filterIter(g, v => v % possiblePrime != 0);
    }
}

// print the first 10 primes
for (const prime of sieve(10)) {
    console.log(prime);
}

【讨论】:

【解决方案2】:

使用以下内容,您只能从流中获得奇数:

do {
    val = g.next().value;
} while (!(val%2));

你可以在你的代码中测试它:

function* nextNaturalNumber(n) {
    yield n;
    yield* nextNaturalNumber(n + 1);
}   

function* sieve(n) {
    let count = 0;
    let g = nextNaturalNumber(2);
    while (count++ < n) {
       let val;
       do {
             val = g.next().value;
        } while (!(val%2));
        
        const possiblePrime=val;
        yield possiblePrime;
    }
}

// print the first 10 primes
for (const prime of sieve(10)) {
    console.log(prime);
}

【讨论】:

    猜你喜欢
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 2018-06-20
    • 2018-02-04
    • 2016-08-09
    • 1970-01-01
    相关资源
    最近更新 更多