2016-07-21 15 views
0

私は以下のシャッフルプログラムを書いて"Will It Shuffle?"まで走りました。結果はコンソールで動作していることを示しています。それは配列をシャッフルしています。しかし、ウェブサイトは私にすべての赤いボックスを表示し、私のコードで何かが間違っていると思うようにしていますが、私はそれを見ません。私のシャッフルプログラムに何が問題なのですか?

function shuffle (array) { 
    var arr = [], 
     length = array.length, 
     el; 

    while (length > 0) { 
     var randomEl = Math.floor(Math.random() * (length - 0) - 0); 
     if (length > 1) { 
     el = array.splice(randomEl,1); 
     } else { 
     el = array.splice(0,1); 
     } 
     arr.push(el[0]); 
     length -= 1; 
    } 

    return arr; 
} 
+1

コンソールでテストしましたか?あなたはそれらを実行しましたか?あなたは戻ってくる、彼らは戻っていない。彼らは配列を変更する、あなたはしません – epascarello

+0

1から10の配列のテストから、それは問題がWill It Shuffleのサイトにあると思うほどランダムに見えます。 – HyperNeutrino

+0

@epascarello、はい、何度も。誰かが私の最後のソーティングコードが良くないと言って、私にそのウェブサイトを送った。私はこの1つを書いて、そのウェブサイトでそれをテストし、そのセルは完全に赤色です。申し訳ありませんが、JSの新機能です。 – BeerBeard

答えて

1

このページでは、in-placeソートが予想されるため、関数の戻り値は無視されます。あなたのコードの末尾にこれを追加した場合

は、それが期待どおりに動作:

array.push(...arr); 

ます。また、直接その場でそれを行うことができます。

function shuffle (array) { 
    var length = array.length; 
    while (length) { 
    var randomEl = Math.floor(Math.random() * length); 
    var el = array.splice(randomEl, 1); 
    array.push(el[0]); 
    --length; 
    } 
} 
+0

ありがとう、@Oriol。私はまだJSを学んでいるので、 "... arr"を押すことに慣れていません。それが省略記号と一緒に動作する理由を説明できますか? – BeerBeard

+1

@BeerBeardこれは[スプレッドオペレータ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)です。たとえば、 'arr = [1,2,3]'をお持ちの場合、 'array.push(... arr)'は 'array.push(1,2,3)'のように動作します。つまり、 'arr'のすべての要素を' array'にプッシュします。 – Oriol

+0

他の回答が参考になりましたが、回答者の皆さん、特にスプレッドオペレータ、インプレースソート、インプレースで実行しているコードの別のバリエーションなどでお答えいただきありがとうございます。良い学習と感謝。 – BeerBeard

1

彼らは、配列を変更し、あなた配列を変更しないでください。

元の配列を変更する必要があります。新しい配列を返さないでください。

function shuffle (array) { 
    var arr = [], 
     length = array.length, 
     el; 

    while (length > 0) { 
     var randomEl = Math.floor(Math.random() * (length - 0) - 0); 
     if (length > 1) { 
     el = array.splice(randomEl,1); 
     } else { 
     el = array.splice(0,1); 
     } 
     arr.push(el[0]); 
     length -= 1; 
    } 

    //replace array with the new items 
    //it is like using concat, but does not produce a new array, 
    //just appends it to the original which has zero items in it. 
    Array.prototype.push.apply(array, arr); 



} 
+0

私はあなたのことを知っていますが、この答えはあまり明確ではありません。 [私からのdownvote] [BTWは]]詳細を教えてください。 – HyperNeutrino

1

あなたがやっていることは、オリジナルの要素をシャッフルして新しい配列を作成することです。

しかし、戻って渡された配列を見ると、シャッフルされずに空になっていることがわかります。どうやら、これは「シャッフルされるの?あなたに求めています。

splice()とpush()はどちらも、それらのメソッドを呼び出す配列を常に突然変異させます。

.push(... arr)に関するご質問にお答えするために、javascriptのエリプスは、最新バージョンのEcmaScript 2015を搭載した機能です。これは「スプレッドオペレータ」です。

"spread"配列を持つ関数を呼び出すと、配列の内容を別の引数として呼び出すようなものになります。例えば、

array.push(...[1,2,3]) 

アレイにコンマで区切られた引数の任意の数を追加することができ

array.push(1,2,3) 

プッシュ()を呼び出すと同じです。したがって、ループされたスプライスで配列の引数を空にした後、スプレッド演算子を使用して、新しく作成したarrの内容を空の配列にプッシュすることができます。

関連する問題