2017-07-12 1 views
1

コードワーズのWhat's up next?チャレンジを解決しようとしています。チャレンジには、最初の入力として値のシーケンスがあり、2番目の入力としてシーケンス内のアイテムがあり、指定したアイテムの直後にシーケンス内のアイテムを返す必要があります。与えられた例 -JavaScript:ジェネレータと生成されたシーケンスの使用を理解する

nextItem([1, 2, 3, 4, 5, 6, 7], 3) # 4 
nextItem("testing", "t") # "e" 

は、最初の引数として値のシーケンスを生成するために発電機を使用するサンプル・テスト・ケースがあり、これは私が困惑してるところです - 私は

function* countFrom(n) { for (let i = n; ; ++i) yield i; } 
Test.assertEquals(nextItem(countFrom(1), 12), 13); 

この発電機がどのように機能するのか分かりません。

function nextItem(xs, item) { 
    // TODO: Implement me 
    // if sequence is a string, like "testing" 
    if (typeof xs === "string") { 
    xs = arguments[0].split(''); 
    } 

    // if sequence is an array(not a generator sequence) 
    if(Array.isArray(xs)) { 
    if(!xs.includes(item) || xs.lastIndexOf(item) === xs.length -1) { 
     return undefined; 
    } 
    return xs[xs.indexOf(item)+1]; 
    } 
    else { 
    // if seqeunce is from a generator 
    let temp = []; 
    for(let i = xs.next().value; i <= arguments[1]; i++) { 
     temp.push(i); 
    } 
    xs = temp; 
    return xs[xs.length-1] + 1; 
    } 

} 
- テストケースを見ると、私は最初に私のコードだった、発電機は1〜12のシーケンスを生成し、その後わずか12後の数字は、その上で13

すなわちを返却する必要があると思いました

は、これは約半分のテストケースを失敗した -

Time: 326ms Passed: 9 Failed: 9 
Test Results: 
Test Passed: Value == 4 
Test Passed: Value == undefined 
Test Passed: Value == undefined 
Test Passed: Value == 'e' 
Test Passed: Value == '!' 
Test Passed: Value == undefined 
Test Passed: Value == undefined 
Test Passed: Value == 701 
Expected: undefined, instead got: 661 
Test Passed: Value == 661 
Expected: 664, instead got: 661 
Expected: undefined, instead got: 661 
Expected: undefined, instead got: 661 
Expected: 664, instead got: 661 
Expected: 662, instead got: 661 
Expected: undefined, instead got: 661 
Expected: undefined, instead got: 661 
Expected: 662, instead got: 661 

私はここで発電機を使用する方法の私の理解は欠陥があるかなり確信しています。この行では、nextItem(countFrom(1), 12)では、生成されたシーケンスが1から12ではないと思います。私は、「ある」シーケンスを生成し、関数に12を渡すとシーケンス13の次のアイテムを返します。

私は発電機でこのarticleを通過しましたが、ここでそれをどのように適用するかはわかりません。

この難題を解決する方法についての説明はありがたいです。

答えて

2

この発電機の仕組みを理解しています。テストケースを見ると、最初はジェネレータが1から12までのシーケンスを生成すると考えました。

いいえ、ジェネレータは無限のシーケンスを生成します。ループには条件がないことに注意してください。イテレータでnext()を呼び出し、次のyieldにステップを進める限り、ループは永遠に実行されます。

この問題を解決する方法については、私はどんな説明もあります。

主なポイントは、文字列、配列、ジェネレータはすべてiterableです。あなたはそれらを区別し、それぞれ異なるケースを書かなければなりません。それを気にしない、

function nextItem(xs, item) { 
    const iterator = xs[Symbol.iterator](); 
    var value = NaN, // bad trick: a value known not to ===item 
     done = false; 
    while (!done && value !== item) 
    ({value, done} = iterator.next()); 
    return iterator.next().value; 
} 

、あるいは簡単に、ちょうどfor ofループを使用します:あなたはちょうどそれを通じてジェネリック[Symbol.iterator]()インターフェースと進歩を使用する必要があり、最初の例では

function nextItem(xs, item) { 
    var found = false; 
    for (const x of xs) { 
    if (found) return x; 
    found = x === item; // whether to be returned in the next iteration 
    } 
} 
+0

を ' iteratorもiterableであるため、 'while'(iteratorのconst値)if(value === item)break;のためにswapすることもできます。 – loganfsmyth

+0

@loganfsmythニースは、それを考えなかったので、2番目の例で 'found'フラグを避けることができます。最初のスニペットでは明示的に '.next()'を使いたかったのですが、 – Bergi

+0

@Bergiありがとうございました!今日は新しいことを学び、とても便利です。 –

関連する問題