分享 JavaScript 高阶生成器:进行过滤以生成素数。
生成器大家都知道是怎么一回事,但是高阶生成器又是什么东西呢?今天小编就带着大家来一起了解一下吧……
先上代码:
function* numFrom(start: number) {
while (true) yield start++
}
function* filter(nums: Generator<number>, prime: number) {
for (const n of nums) if (n % prime !== 0) yield n
}
let cur = numFrom(2)
for (let i = 0; i < 10; i++) {
const prime = cur.next()
if (!prime.done) {
console.log(i, ':', prime.value)
cur = filter(cur, prime.value)
}
}
结果:
0 : 2
1 : 3
2 : 5
3 : 7
4 : 11
5 : 13
6 : 17
7 : 19
8 : 23
9 : 29
其中函数 filter
传入一个生成器,返回一个新的生成器,我们可以把它称为高阶生成器。
function* filter(nums: Generator<number>, prime: number) {
for (const n of nums) if (n % prime !== 0) yield n
}
它的作用是过滤掉 nums: Generator<number>
生成的数中能被 prime
整除的数:
const gen = filter(numFrom(10), 3)
for (let i = 0; i < 10; i++) {
const n = gen.next()
if (!n.done) console.log(n.value)
}
结果:
10
11
13
14
16
17
19
20
22
23
可以看到,3
的倍数,12
、15
、18
、21
已经被过滤掉了。
如果我们再把函数返回值作为参数传给 filter
,就能过滤掉多个值了:
let gen = filter(numFrom(10), 3) // 从 10 开始,不能被 3 整除的数
gen = filter(gen, 5) // 从 10 开始,不能被 3 和 5 整除的数
...
只要我们不断把当前的生成器和产生的素数传入,我们就能够实现过滤,相当于使用筛法生成素数。
let cur = numFrom(2)
for (let i = 0; i < 10; i++) {
const prime = cur.next()
if (!prime.done) {
console.log(i, ':', prime.value)
cur = filter(cur, prime.value) // 产生新的生成器
}
}
numFrom(2) -> filter(2) -> filter(3) -> filter(5) -> filter(7) ...
如果还不太清除,可以在控制台打印详细过程:
function* numFrom(start: number) {
while (true) {
console.log('\nnum yield', start)
yield start++
}
}
let filterDeep = 0
function* filter(nums: Generator<number>, prime: number) {
const deep = filterDeep++
for (const n of nums)
if (n % prime !== 0) {
console.log(`filter yield[${deep}] ${n}`)
yield n
} else console.log(`filtered[${deep}] ${n} by ${prime}`)
}
let cur = numFrom(2)
for (let i = 0; i < 10; i++) {
const prime = cur.next()
if (!prime.done) {
console.log(i, ':', prime.value)
cur = filter(cur, prime.value)
}
}
结果:
num yield 2
0 : 2
num yield 3
filter yield[0] 3
1 : 3
num yield 4
filtered[0] 4 by 2
num yield 5
filter yield[0] 5
filter yield[1] 5
2 : 5
num yield 6
filtered[0] 6 by 2
num yield 7
filter yield[0] 7
filter yield[1] 7
filter yield[2] 7
3 : 7
num yield 8
filtered[0] 8 by 2
num yield 9
filter yield[0] 9
filtered[1] 9 by 3
num yield 10
filtered[0] 10 by 2
num yield 11
filter yield[0] 11
filter yield[1] 11
filter yield[2] 11
filter yield[3] 11
4 : 11
num yield 12
filtered[0] 12 by 2
num yield 13
filter yield[0] 13
filter yield[1] 13
filter yield[2] 13
filter yield[3] 13
filter yield[4] 13
5 : 13
num yield 14
filtered[0] 14 by 2
num yield 15
filter yield[0] 15
filtered[1] 15 by 3
num yield 16
filtered[0] 16 by 2
num yield 17
filter yield[0] 17
filter yield[1] 17
filter yield[2] 17
filter yield[3] 17
filter yield[4] 17
filter yield[5] 17
6 : 17
num yield 18
filtered[0] 18 by 2
num yield 19
filter yield[0] 19
filter yield[1] 19
filter yield[2] 19
filter yield[3] 19
filter yield[4] 19
filter yield[5] 19
filter yield[6] 19
7 : 19
num yield 20
filtered[0] 20 by 2
num yield 21
filter yield[0] 21
filtered[1] 21 by 3
num yield 22
filtered[0] 22 by 2
num yield 23
filter yield[0] 23
filter yield[1] 23
filter yield[2] 23
filter yield[3] 23
filter yield[4] 23
filter yield[5] 23
filter yield[6] 23
filter yield[7] 23
8 : 23
num yield 24
filtered[0] 24 by 2
num yield 25
filter yield[0] 25
filter yield[1] 25
filtered[2] 25 by 5
num yield 26
filtered[0] 26 by 2
num yield 27
filter yield[0] 27
filtered[1] 27 by 3
num yield 28
filtered[0] 28 by 2
num yield 29
filter yield[0] 29
filter yield[1] 29
filter yield[2] 29
filter yield[3] 29
filter yield[4] 29
filter yield[5] 29
filter yield[6] 29
filter yield[7] 29
filter yield[8] 29
9 : 29
参考:
通道 – Kotlin 官方文档 https://book.kotlincn.net/text/channels.html
作者:terry,如若转载,请注明出处:https://www.web176.com/news/frontend/28080.html