I'm trying to write a function that can take either a list or a generator as input. For example, this function:
function x(l) {
for (let i of l) {
console.log(i);
}
for (let i of l) {
console.log(i);
}
}
If I run it like this:
x([1,2,3])
It will display:
1
2
3
1
2
3
Now I want to use a generator as input:
function *y() {
yield 5
yield 6
yield 7
}
These don't work:
x(y())
x(y)
The output is:
5
6
7
undefined
What do I need to do so that I can make it work?
In terms of Java, the function y
above is a Generator and y()
is an Iterator. [1,2,3]
is a list and in Java, lists are generators. But the javascript for loop expects an iterator, which means that it can't be restarted. This seems like a flaw in javascript that the for loop works on iterators and not generators.
答案 0 :(得分:2)
生成器cannot be used multiple times。如果要迭代两次,则需要通过调用生成器函数两次来创建两个生成器。
当函数期望迭代(在for … of
循环中使用)时,您可以执行的操作是从生成器函数动态创建一个:
x({[Symbol.iterator]: y})
如果你想编写你的函数x
以便它可以使用迭代器或生成器函数,你可以使用像
getIterator(val) {
if (typeof val == "function") // see also https://stackoverflow.com/q/16754956/1048572
return val();
if (typeof val[Symbol.iterator] == "function")
return val[Symbol.iterator]();
throw new TypeError("not iterable!")
}
function x(l) {
for (let i of getIterator(l)) {
console.log(i);
}
for (let i of getIterator(l)) { // call getIterator again
console.log(i);
}
}
x(y);