力扣的js入门免费题刷完了,开始自己找题练练,顺便捡捡知识点
力扣2649
1.思路
一眼递归,但事实证明也可以直接flat手撕。
arr.flat(Infinity) //直接扁平化到最底层
涉及到了一些关于生成器和异步编程相关的知识点,学一下。
2.关于生成器函数
在JavaScript中,星号(*
)用于定义生成器函数(generator function)。生成器函数是一种特殊类型的函数,它允许你在函数执行过程中暂停和恢复,同时保持函数的状态。
以下是关于生成器函数和星号的一些关键点:
- 生成器函数定义:
使用星号定义生成器函数,例如:
function* generatorFunction() {// ...
}
- 生成器函数执行:
调用生成器函数并不会立即执行其内部的代码,而是返回一个生成器对象(generator object)。生成器对象实现了迭代器协议,因此可以使用next()
方法来逐步执行生成器函数内部的代码。 yield
关键字:
在生成器函数内部,yield
关键字用于暂停函数执行,并返回一个值。后续调用生成器对象的next()
方法会恢复函数执行,直到下一个yield
表达式。yield*
表达式:
yield*
用于委托给另一个生成器函数或可迭代对象。在你提供的inorderTraversal
函数中,yield*
用于递归地遍历数组,并逐个产出元素。
以下是对你提供的inorderTraversal
函数的解释:
var inorderTraversal = function* (arr) {for (const item of arr) {if (Array.isArray(item)) {// 如果当前项是一个数组,递归地委托给inorderTraversal生成器// 并产出递归遍历的结果yield* inorderTraversal(item);} else {// 如果当前项不是数组,直接产出该项yield item;}}
};
在这个函数中,当遇到一个数组项时,它使用yield*
来委托给inorderTraversal
自身,从而实现对嵌套数组的深度优先遍历。对于非数组项,它使用yield
来产出该项。最终结果是,调用这个生成器函数可以逐个产出所有非数组元素,无论它们在原始数组中的嵌套深度如何。
例如,使用这个生成器函数:
const nestedArray = [1, [2, [3, 4], 5], 6];
const traversal = inorderTraversal(nestedArray);
for (const value of traversal) {console.log(value); // 输出: 1, 2, 3, 4, 5, 6
}
这将按照中序遍历的方式打印出嵌套数组中的所有数字。
5. 使用.next()
方法控制的案例
当然,以下是一个使用生成器函数和next()
方法的简单案例。这个例子中的生成器函数会逐步产出一系列的斐波那契数列。
function* fibonacciGenerator() {let a = 1, b = 1;while (true) {yield a;[a, b] = [b, a + b]; // 使用数组解构赋值来交换a和b的值,并计算下一个斐波那契数}
}
// 创建生成器对象
const fib = fibonacciGenerator();
// 使用next()方法来获取斐波那契数列的前10个数字
for (let i = 0; i < 10; i++) {console.log(fib.next().value);
}
执行上述代码将输出斐波那契数列的前10个数字:
1
1
2
3
5
8
13
21
34
55
解释:
fibonacciGenerator
是一个生成器函数,它使用yield
来产出斐波那契数列的每个数字。- 在生成器函数内部,我们使用一个无限循环来持续计算斐波那契数列的下一个数字,并在每次循环中使用
yield
来产出当前的数字。 - 创建生成器对象
fib
后,我们通过循环调用next()
方法10次来获取数列的前10个数字。 - 每次调用
next()
方法时,生成器函数都会从上次yield
的地方继续执行,计算下一个斐波那契数,并再次yield
它。 next().value
返回的是yield
产出的值,即当前的斐波那契数。
注意,由于生成器函数内部是一个无限循环,如果你不限制next()
的调用次数,它会无限产出斐波那契数列的数字。在实际使用中,你通常会根据需要来决定调用next()
的次数,或者使用其他逻辑来终止生成器函数的执行。
3.省流总结
· generator函数,也是用于解决异步编程问题的一个方法。很标志性的结构是比一般函数多了一个*
function*(){}
,返回的是内部指针。在函数内部有yield
,意思是在这里移交执行权跳到下一个任务。
· 使用前先创建生成器对象
· 可以通过.next()
来获取生成器对象,以及用value属性调取对象值