2011-07-21 8 views
2

このフィドルhttp://jsfiddle.net/5L8Q8/28/では、黒いボタンをクリックすると、配列から2つの値(赤または青)のいずれかをランダムに選択します。ランダムに選択された値はranに割り当てられます。私の実際の生活のアプリケーションでは、その配列に16の要素があります。JavaScript:この問題を解決するには再帰関数が必要ですか?

ピンクの「再生」ボタンの場合は、同じ配列からランダムな要素を選択しますが、最後に選択したものと同じでないことを確認します。

playagainをクリックするとranlastranに割り当てられ、次にランダムに選択された値と比較され、同じ場合はランダムに選択されます。しかし、私が持っている方法は、(playagainの完了時に)ranが異なることを保証するものではありません。

コメント2が下のコードにある再帰関数が必要だと思いますが、作成しようとするとコードが壊れてしまいます。

以下のコードの3つのコメントにコメントできますか?

注意、あなたが代わり場合のwhileループを使用することができます...

$("#playagain").click(function(){ 
    lastran = ran; 


    ran = getRandom(myArray, true); 

    if (ran === lastran) { 

     ran = getRandom(myArray, true); //1. do I need to return this? 

      //2. want to test ran === lastran again.. How to set up recursive function? 

    } else { 

     return; //3.is this the right thing to do here? 
    } 

}); 
+2

は、誰もが相対的な初心者です、そうでないと思っても、それらの人々を心配しないでください。 – davin

答えて

2

私は相対的な初心者ですので、このコードはおそらくひどいです。

while(ran == lastran) 
{ 
    ran = getRandom(myArray, true); 
} 

別の値になるまで試し続けます。

+0

私はあなたがこれを変えることができると言っていました。それは本当です。はい、あなたはran = getRandom(...)が必要です。これは1行にすることもできますが、whileループが動作し、再帰が必要ない理由を理解するのが簡単になると思います。 –

+0

これはあなたがそれを想像したものですか? http://jsfiddle.net/5L8Q8/31/私はそれが良いと思います... – Leahcim

3
while((ran = getRandom(myArray, true)) === lastran) 
    ; 

あなたは何ですか?声明

ran = getRandom(myArray, true) 

getRandom()ranを設定しますが、ranの値を返すだけではありません。だからあなたの完全なコードをすることができ

(これはCから引き継が、JavaScriptでかなり一般的なイディオムです):

$("#playagain").click(function(){ 
    /*var */lastran = ran; 

    while((ran = getRandom(myArray, true)) === lastran) 
     ; 

    // update UI here 

}); 
+0

ありがとうございます。エドガーも正しく答えてくれたので、誰が「受け入れられた答え」を得るのかを見るためにコインを裏返した。残念ながら、あなたは失ってしまいましたが、あなたの助けを大変ありがとうございます。 – Leahcim

+0

エドガーのコードは実際には動作しません:(あなたのメソッドの使い方をしたい場合は、 'run = getRandom(myAray、true)'をコードの先頭に追加する必要があります。 –

+0

これは正しくありませんエドガーのコードhttp://jsfiddle.net/5L8Q8/31/ – Leahcim

0

私はあなたのアプローチはこれに対処するための最良の方法はないと思います。理論的には同じ数字を何回も連続して得ることができ、これは「遅い」忠誠心を作り、必要以上に複雑にしています。それはこのように動作します

getRandom(myArray, true, lastran) 

function getRandom(array, getVal, lastRan) { 
    var key = Math.floor(Math.random() * array.length); 
    if ((!getVal && key == lastRan) || (getVal && array[key] == lastRan)) 
     return getRandom(array, getVal, lastRan); 
    return getVal ? array[key] : key; 
} 

最後のランダムな値を渡してそれを呼び出す:あなたはgetRandom自体再帰的に作ることができる

- if no previous element has been picked pick a number between 0 and the number of elements in your array (16) otherwise pick a number between 0 and #elements-1 (15) 
- if the chosen element is greater or equal to the last element picked add 1 to it 
- store this index number as the last picked element 
- return the array[picked-element]'s value 
+0

ありがとうございました。 – Leahcim

0

:テキストに

別のアプローチ。検索された最後のランダムな値は、常にgetRandomに渡されます。最初の条件では、getValtrueかどうかに応じて、この値の複製を生成したかどうかを確認します(キー自体または配列の対応する値を使用して)。その場合は、getRandomを呼び出した結果を返します。もう一度、最後に使用された乱数を渡します。これは、必要な回数だけ発生する可能性があります。

getRandomへのこれらの呼び出しのいずれかが新しい数値を生成すると、最初の条件式の式はfalseになります。この場合、2番目のreturnステートメントを介して必要な値を返し、getRandomへのすべての再帰呼び出しを「アンロール」します。

+0

非常に興味深い。ありがとうございました。正直言って、 "if"と "return"の行のロジックを理解するのは難しいです。あなたが初心者に説明する時間があれば、私は間違いなくそれを感謝します。 – Leahcim

+0

@Michael - 説明が追加されました。 –

+0

ありがとうございました。 – Leahcim

1

実行ごとに、単に配列からその「キー」を削除し、lastranをその最後に押してください。(それぞれのステップの呼び出しごとにgetRandomの値を返すことを覚えておいてください。次に、次のように更新されたgetRandom関数を#buttonと#playagainの両方に使用できます。 http://jsfiddle.net/ghostoy/5L8Q8/32/

function getRandom(array, getVal) { 
    var key = Math.floor(Math.random() * array.length), 
     value = array[key]; 

    if (lastran) { 
     array.push(lastran); 
    } 

    array.splice(key, 1); 
    lastran = value; 

    if (getVal) { 
     return value; 
    } 
    return key; 
} 
+0

私にこれを見せていただきありがとうございます。それは私が学ぶのを助けるでしょう。 – Leahcim

+0

+1。選択された値を配列から削除して、次の選択が最後の選択と同じになることができないようにする方がはるかに優れています。元の配列のコピーを保持するか、選択した配列を新しい配列に入れるかのどちらかです。最初のものが使い尽くされたら、選択したものと入れ替えます。だからあなたはもう一方を空にしながら一方を埋める、そして逆にする。 :-) – RobG

関連する問題