2012-02-08 18 views
0

配列のエントリを取り、順序をシャッフルするjavascriptを書きました。それはそれが必要なようにコンパイルされていません。 forループを1回だけ実行しているようです。私は何が欠けていますか?JavaScript配列shufflerが動作しない

//random number between 1 and num 
function randInt(num){ 
    return Math.floor(num*Math.random()+1); 
} 

//shuffles deck (array) of any size 
function shuffle(array){ 
    var newArray = new Array(); 
    var n = array.length; 
    for(i=0; i<n; i++){ 
     var entry = randInt(array.length) - 1; 
     newArray[i] = array[entry]; //assigns random entry in initial array to  new array 
      array = array.splice(entry, 1); //removes the entry that was stored into newArray 
    } 
    array = newArray; 
} 
+2

"i" のvar' 'と宣言します!シャッフルするのは本当に無駄な方法です。たとえそれをうまく機能させることができたとしても。ウィキペディアの[Fisher-Yates shuffle article](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)を参照してください。 '.slice()'を呼び出す理由はありません。 – Pointy

+0

ループの外側で 'var entry'を宣言しています。JSLint manを実行してください:P – Halcyon

+0

@FritsvanCampen:ループの外側では' entry'は使用されません.JSは複数のvar文。すべての変数は関数にスコープされていますが、ループ内に保持することをお勧めします。次の開発者には、ループ内でのみ使用されることを意味します。 –

答えて

4
  • array.splicearrayを修正、削除アイテム(複数可)を返します。 randInt
array.splice(entry, 1); 
  • + 1をし、その後- 1やってはsuperflouousようだ:あなたはとてもだけではなく、arrayを上書きするのでこれを行う、要素を破棄します。
  • var i = 0を使用してください(私の最後の点を見ていますが)。
  • new Array()の代わりに[]を使用します。後者は一般的には使用されないからです。
  • 戻る代わりにarrayを上書きする新しい配列:
return newArray; 
  • 長さが少ない1たびになるとあなたはもうarrayので、あなたがnまでループすることはできませんを変更します。 forループの代わりにwhile(array.length > 0) { ... }が必要な場合があります。
+0

非常に迅速に分析が行われました。 – mrtsherman

+0

Agh!もちろん。私は私の前にvarの不足を拾っていないために愚かな気がします。 randIntは正の整数が必要な場所で使用されます。それ以外の場合は、この調整を行いました。あなたの最後の点については、この問題を回避するために配列の最初の長さを設定しますが、whileループはもっときれいです。ありがとう。 – amdilley

0

ホイール(この場合はシャッフル)を再作成する必要はありません。

function shuffle(o){ 
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); 
    return o; 
} 

http://snippets.dzone.com/posts/show/849

+0

これはこの問題が[ここ](http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete)に苦しんでいるようです.html)。 – pimvdb

0

なぜカスタム関数でarray.sortを使用しないのですか?

function shuffle(array) { 
    array.sort(function(a, b) { 
     return (Math.random() < 0.5) ? 1 : -1; 
    }); 
} 
+1

これはシャッフルするためのひどい方法です。 – Pointy

+0

... more:それはひどい理由はいくつかあります。あなたは本当にソートが何をするのか分からないので、すべての要素が確実にソートされるかどうかを言うのは難しいです。関数呼び出しのために高価です。また、2つの要素の比較が2回以上比較されるときに異なるため、並べ替えが非常に混乱し、終了しない可能性があります。 – Pointy

3

基本的な問題は、JavaScriptがあたかも参照渡し言語であるかのように記述されていることです。そうではありません;それは価値による呼び出しです。したがって、関数の最後の行は構文的には正しいが、機能的には役に立たない。

はここフィッシャーイエーツシャッフルです:

function fyShuffle(a) { 
    if (a.length < 2) return; 
    for (var i = a.length; --i >= 1;) { 
    var j = ~~(Math.random() * (i + 1)), tmp; 
    tmp = a[j]; 
    a[j] = a[i]; 
    a[i] = tmp; 
    } 
} 
0
Array.prototype.shuffle= function(){ 
    var i, L= this.length; 
    while(--L){ 
     i= Math.floor(Math.random()*L); 
     this[L]= this.splice(i, 1, this[L]) 
    } 
    return this; 
} 

スプライスを使用して直接assignment-よりも高速である場合には言い難いが

Array.prototype.shuffle= function(){ 
    var i, temp, L= this.length; 
    while(--L){ 
     i= Math.floor(Math.random()*L); 
     temp= this[i]; 
     this[i]= this[L]; 
     this[L]= temp; 
    } 
    return this; 
} 
関連する問題