2016-09-04 13 views
1

現在、乱数を配列から返すように変更しようとしていますので、各乱数は最後の乱数とは異なります選ばれた新しい乱数を生成する方法(以前の乱数とは異なります)

function randomize(arr) { 
      return arr[Math.floor(Math.random()*arr.length)]; 
     } 

oracleImg = []; 
      for (var i=1;i<=6;i++) { 
      oracleImg.push(i); 
     } 

randOracleImg = randomize(oracleImg); 

私は以下を試しましたが、必ずしも最後の番号と異なる番号を与えているわけではありません。

function randomize(arr) { 
    var arr = Math.floor(Math.random()*arr.length); 
    if(arr == this.lastSelected) { 
      randomize(); 
     } 
     else { 
      this.lastSelected = arr; 
      return arr; 
     } 
} 

どうすればこの問題を解決できますか?

+6

これは常に以前の数値と異なる場合、実際にはランダムではありません。 – stark

+0

数字が2番目と同じかどうかは問題ありませんか、または配列全体をランダムな順序で処理する必要がありますか? – nnnnnn

+0

全くありません。 [0、arr.length]から乱数を選択しています。 – Li357

答えて

1

既存の関数の再帰的なrandomize()呼び出しは、arr引数を渡さず、戻り値で何もしないため意味がありません。その行は次のようになります。

return randomize(arr); 

...それはそれはもはや元の配列を参照するようにあなたがarrを再割り当てしていないことをラインに達する時点でことを除いて。次のバージョンのように追加変数を使用すると効果があります。

配列に要素が1つしかない場合は、その項目をすぐに返すことを確認するテストを追加しました。この場合、毎回別の項目を選択することができないためです。 (関数は、配列が空の場合。undefinedを返す)

function randomize(arr) { 
 
    if (arr.length < 2) return arr[0]; 
 
    var num = Math.floor(Math.random()*arr.length); 
 
    if(num == this.lastSelected) { 
 
     return randomize(arr); 
 
    } else { 
 
     this.lastSelected = num; 
 
     return arr[num]; 
 
    } 
 
} 
 

 
document.querySelector("button").addEventListener("click", function() { 
 
    console.log(randomize(["a","b","c","d"])); 
 
});
<button>Test</button>
元の関数は、ランダムな配列に インデックスを返すように見えた

ますが、私の答えに示すコードを返します。ランダム配列要素

あなたの関数を呼び出す方法は、関数内でthisがウィンドウであることを意味することにも注意してください。それは動作しますが、基本的にlastSelectedはグローバル変数です。

グローバル変数を不必要に作成することに熱心ではないことを考えれば、ここではグローバル変数を持たない代替実装があります。私の意見では単純なwhileループは "試し続ける" 「Xが起こるまで:コードの下

var randomize = function() { 
 
    var lastSelected, num; 
 
    return function randomize(arr) { 
 
     if (arr.length < 2) return arr[0]; 
 
     while (lastSelected === (num = Math.floor(Math.random()*arr.length))); 
 
     lastSelected = num; 
 
     return arr[num]; 
 
    }; 
 
}(); 
 

 
document.querySelector("button").addEventListener("click", function() { 
 
    console.log(randomize(["a","b","c","d"])); 
 
});
<button>Test</button>

+0

インデックス内ではなく、配列内のアイテムを返すようにしています。したがって、7行目は "return arr [num];"でなければなりません。 – Feathercrown

+0

@Feathercrown - 真。私は私の答えでそれを語った。質問に追加された余分なコードを見ても、配列には1から6までの数字が含まれているため、配列は冗長であるように見えます。 – nnnnnn

+0

このコードは、違いが重要な場所で使用される可能性があるためです。 – Feathercrown

1

は一例であり、論理は単純です(範囲は0〜1000である)それは99個の数字を生成し、すべてがユニークでランダムになりますちょうど乱数を追加する一時的な配列に格納し、既に生成されている場合は新しいrandomを比較します。

var tempArray = []; 
 
var i=0; 
 
while (i != 99) { 
 
    var random = Math.floor((Math.random() * 999) + 0); 
 
    if (tempArray.indexOf(random)==-1) { 
 
     tempArray.push(random); 
 
     i++; 
 
    } else { 
 
    continue; 
 
    } 
 
} 
 
console.log(tempArray);

+0

質問を再読してください。彼はちょうど** **以前のものとは違って、**すべての**以前のものとは違うものを望んでいます。 –

1

あなたは常に配列から別の番号を返すようにしたい場合は、代わりにシャッフル、ランダム化しないでください!*

最も簡単なフェア(真にランダム)シャッフリングアルゴリズムがありますFisher-Yatesアルゴリズム。 mistake Microsoft did and try to abuse .sort() to implement a shuffleと同じにしないでください。ただ、Fisher-Yates (otherwise known as the Knuth shuffle)を実装:

// Fisher-Yates shuffle: 
// Note: This function shuffles in-place, if you don't 
//  want the original array to change then pass a copy 
//  using [].slice() 
function shuffle (theArray) { 
    var tmp; 
    for (var i=0; i<theArray.length;i++) { 
     // Generate random index into the array: 
     var j = Math.floor(Math.random()*theArray.length); 

     // Swap current item with random item: 
     tmp = theArray[i]; 
     theArray[j] = theArray[i]; 
     theArray[i] = tmp; 
    } 
    return theArray; 
} 

だからやる:あなたは画像が不足して処理する方法

shuffledOracleImg = shuffle(oracleImg.slice()); 

var i=0; 

randOracleImg = shuffledOracleImg[i++]; // just get the next image 
             // to get a random image 

はあなた次第です。 iTunesのようなメディアプレーヤーやiPhone、iPad、iPodの音楽プレーヤーは、再生をやり直すか、最初からやり直すかを選択できます。一部のカードゲームソフトウェアが改造され、再び開始されます。

注:私のペットピープスの1つは、シャッフルの代わりにランダム化する音楽プレーヤーソフトウェアです。いくつかの実装では、次の曲が現在の曲と同じであるかどうかをチェックしないので、2回再生した曲(避けたい曲)と2曲を終了します決して上がることはありません。シャッフルしてシャッフル再生リストを最初から最後まで再生すると、両方の問題を回避できます。 CDプレーヤーの製造元は正しいと思った。 MP3プレーヤーの開発者は間違ってしまう傾向があります。

+0

ありがとう、私はこの答えが大好きです。非常に単純で論理的です。 –

1

ここでは、常に最後のものとは異なる乱数を保証するバージョンです。さらに、生成されたランダム値の最大値と最小値を制御することができます。デフォルトは最大:100、最小:1

+0

ありがとうSufian –