2016-07-21 20 views
0

Ich schrieb ein Shuffling-Programm unten und lief es durch "Will It Shuffle?". Die Ergebnisse scheinen zu zeigen, dass es in der Konsole funktioniert. es mischt das Array. Aber die Website zeigt mir eine rote Box, die mich glauben lässt, dass mit meinem Code etwas nicht stimmt, aber ich sehe es nicht.Was ist falsch an meinem Shuffling-Programm?

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

Haben Sie es in der Konsole getestet? Hast du ihre laufen lassen? Du kommst zurück, sie nicht. Sie ändern das Array, Sie nicht – epascarello

+0

Von einem Test auf einem Array von 1 bis 10, sieht es zufällig genug, dass ich denke, das Problem liegt in der Will It Shuffle-Site. – HyperNeutrino

+0

@epascarello, Ja, viele Male. Jemand hatte gesagt, mein letzter Sortiercode sei nicht gut und schickte mir diese Website. Ich habe dieses hier geschrieben, es auf dieser Website getestet und die Zellen sind komplett rot, obwohl die Konsole mir zeigt, dass es das Array gut mischt. Entschuldigung, neu bei JS. – BeerBeard

Antwort

1

Diese Seite ignoriert den Rückgabewert der Funktion, weil sie eine in-place Art erwartet.

Wenn Sie diese am Ende des Codes hinzufügen, funktioniert es wie erwartet:

array.push(...arr); 

Sie auch direkt an Ort und Stelle tun:

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

Danke, @Oriol. Ich lerne immer noch JS, daher ist mir das Drücken von "... arr" nicht vertraut. Kannst du erklären, warum das auch mit den Ellipsen funktioniert? – BeerBeard

+1

@BeerBeard Das ist der [Spread-Operator] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). Wenn Sie zum Beispiel 'arr = [1,2,3]' haben, verhält sich 'array.push (... arr)' wie 'array.push (1,2,3)'. Das heißt, es drückt alle Elemente von 'arr' auf 'array'. – Oriol

+0

Ich fand die anderen Antworten hilfreich, aber ich schätze Ihre Antwort sehr, vor allem die Quellen, die Sie auf Spread-Operator, In-Place-Sortierung und eine andere Variante meines Code in-Place zur Verfügung gestellt. Gutes Lernen und Danke. – BeerBeard

1

Sie verändern das Array, Sie ändere das Array nicht.

Sie müssen das ursprüngliche Array ändern und kein neues Array zurückgeben.

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

Ich weiß, was du meinst, aber diese Antwort ist nicht sehr klar. [BTW no downvote von mir :)] Bitte erläutern. – HyperNeutrino

1

Was Sie tun, ist ein neues Array mit den Elementen des Originals neu zu erstellen.

Wenn Sie jedoch zurückgehen und das Array ansehen, das Sie übergeben haben, werden Sie feststellen, dass es nicht gemischt, sondern geleert wurde. Anscheinend ist das nicht was "wird es mischen?" bittet dich zu tun.

splice() und push() mutieren beide immer das Array, das Sie diese Methoden aufrufen.

Um Ihre Frage zu .Push (... arr) zu beantworten, ist ein elipses in Javascript eine Funktion, die mit der neuesten Version, EcmaScript 2015 angekommen ist. Es ist der "Spread-Operator".

Wenn Sie eine Funktion mit einem "Spread" -Array aufrufen, ist das so, als würde man die Funktion mit dem Inhalt des Arrays als separate Argumente aufrufen. Zum Beispiel

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

ist die gleiche wie

array.push(1,2,3) 

Push() aufrufen kann eine beliebige Anzahl von durch Kommas getrennte Argumente zu einem Array hinzuzufügen. Nach dem Leeren des Array-Arguments mit Ihren geloopten Spleißen können Sie den Inhalt des neu erstellten arr mithilfe des Spread-Operators in das leere Array verschieben.