2016-09-02 20 views
2

ジェネレータ用のhasNext()メソッドはどのように実装しますか?私はreturnステートメントとしてジェネレータを追加し、クロージャから降伏するような多くのオプションを試しました。それを印刷して、最初の値を取得し、その後などを使用して、それらのどれも実際に働いた。hasNext()for ES6 Generator

How to loop the JavaScript iterator that comes from generator?のように使用できますが、hasNext()を追加できるかどうかは不思議です。

あなたが start + 1 < endかどうかをチェックすることにより Booleanとして定義 hasNextを持つ rangeからオブジェクトを作成して返すことができ
function *range(start,end){ 

    while(start < end){ 
     yield start; 
     start++ 
    } 
} 

let iterator = range(1,10); 

// so I can do something like this. 
while(iterator.hasNext()){ 
    console.log(iterator.next().value); 
} 
+2

引用疑問がはっきり 'done'、この場合には使用すべきであると述べています。 'hasNext'はジェネレータの目的に反し、遅れて反復され、次の' next() 'までの最後の反復であるかどうかは分かりません。 – estus

+0

私はそれを得て、私はちょうどこれについて理由を考えようとしています。 「hasNextがジェネレータの目的を無視している」とはどういう意味なのか分かりません。 –

+2

@ YasinYaqoobi:値を消費することなく先を見ることはできません。つまり、次の値が*あるかどうかを知るためには、次の値を取得する必要があります。つまり、呼び出し元が 'hasNext'を呼び出し、結果が' true'の場合、呼び出し側はその次の値を取得できません。 –

答えて

4

さもなければ、機能、hasNextを呼び出しますis

for (let iterator = range(1, 10), r; !(r = iterator.next()).done;) { 
    console.log(r.value); 
} 

本当に01を使用したい場合は、あなたにもそれを行うことができますが、それは少し奇妙だ:

const iterator = range(1, 10); 
iterator.hasNext = function hasNext() { 
    const r = this.next(); 
    this.current = r.value; 
    return !r.done; 
}; 
while (iterator.hasNext()) { 
    console.log(iterator.current); 
} 
+0

_const r = this.next(); _ - 取得元の構造体がわかっている場合は値を取得する必要はありません。たとえば、配列を繰り返し処理している場合、 'arr [nextIndex]'が未定義でないかどうかを調べることができます。 'ジェネレータ'関数を使用していません。しかし、私が理解するように、 'map'のような組み込みオブジェクトには必要です。これらの仮定は正しいのでしょうか? –

+1

@Maximus Generators(一般的にIterators)は、基礎的な構造を公開していません。これがこの質問の内容です。もちろん、配列を手動で反復するとき、あなたの "hasNext"は通常の 'index Bergi

+0

ええ、ありがとう、私は少し私のコメントを変更しました。どうぞご覧ください。 'this.current'と' this.done'とは何ですか? –

0

。ジェネレータ.next().donegenerator.next().valueにおけるオブジェクトのfalsehasNextプロパティがtrueに設定されている場合、再帰ループイテレータへの単純な非for…of方法の他のタスクを実行

function* range(start, end) { 
 
    let next =() => start + 1 < end; 
 
    let g = { 
 
    hasNext: next(), 
 
    currentValue: start 
 
    }; 
 
    while (start < end) { 
 
    yield g; 
 
    g.currentValue = ++start; 
 
    g.hasNext = next(); 
 
    } 
 
} 
 

 
let iterator = range(1, 10); 
 

 
function hasNext(gen) { 
 
    let curr = gen.next(); 
 
    if (!curr.done) { 
 
    if (curr.value.hasNext) { 
 
     console.log(`hasNext:${curr.value.hasNext}` 
 
       , `currentValue:${curr.value.currentValue}`); 
 
     hasNext(gen); 
 
    } else { 
 
     console.log(JSON.stringify(curr.value, null, 2)); 
 
    } 
 
    } 
 
} 
 

 
hasNext(iterator);

+2

これは、各ループで 'iterator.next()'を2回呼び出します。 'console.log'のために一度、' while'チェックのために一度。 – cdbajorin

+0

@cdbajorin期待される結果が返されませんか? – guest271314

+1

いいえ、それは他のすべてのロギングを終了します。 'iterator.next()'を変数にバインドし、その変数の 'value'と' done'を使う必要があります。 – cdbajorin

関連する問題