2017-11-11 18 views
0

私は入力としてリストまたはジェネレータのいずれかをとることができる関数を記述しようとしています。たとえば、この機能:forループでES6 javascriptでジェネレータを再利用するにはどうすればいいですか?

function x(l) { 
    for (let i of l) { 
     console.log(i); 
    } 
    for (let i of l) { 
     console.log(i); 
    } 
} 

私はこのようにそれを実行した場合:

x([1,2,3]) 

は、それが表示されます。

1 
2 
3 
1 
2 
3 

は、今私は、入力として発電機を使用したい:

function *y() { 
    yield 5 
    yield 6 
    yield 7 
} 

これらは動作しません:

x(y()) 
x(y) 

出力は次のようになります。

5 
6 
7 
undefined 

私はそれを動作させることができるように何をする必要がありますか?

のJavaの観点から、上記機能yジェネレータy()イテレータあります。 [1,2,3]はリストで、Javaではリストはジェネレータです。しかし、javascript forループは、イテレータを予期しています。つまり、再起動できません。これはjavascriptの脆弱性のようですが、forループはジェネレータではなくイテレータで動作します。

答えて

2

発生器cannot be used multiple times。 2回繰り返す場合は、ジェネレータ関数を2回呼び出して2つのジェネレータを作成する必要があります。

あなたの関数は、反復可能な(つまりfor … ofループ内で使用されている)あなたのジェネレータ関数からその場で1を作成することです期待していたとき、あなたは何ができるか:あなたはあなたの関数を書きたい場合は

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); 
+1

オカイ!わかった。 yはジェネレータ関数、y()はイテレータ、Symbol.iteratorで書いたものは繰り返し使用できる繰り返し可能なものです。 forループはイテレータまたはiterableを取得できます。私はあなたの1ライナーが私のために働くのでiterableが欲しかった。ありがとう! – Eyal

関連する問題