Ich habe ein Array wie folgt:
var arr1 = ["a", "b", "c", "d"];
Wie kann ich es randomisieren / mischen?
Ali
Ich habe ein Array wie folgt:
var arr1 = ["a", "b", "c", "d"];
Wie kann ich es randomisieren / mischen?
Lauren Holst
Hier ist eine JavaScript-Implementierung der Durstenfeld mischteine optimierte Version von Fisher-Yates:
/* Randomize array in-place using Durstenfeld shuffle algorithm */
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Es wählt ein zufälliges Element für jedes ursprüngliche Array-Element aus und schließt es von der nächsten Ziehung aus, wie die zufällige Auswahl aus einem Kartenspiel.
Dieser clevere Ausschluss tauscht das ausgewählte Element mit dem aktuellen aus, wählt dann das nächste zufällige Element aus dem Rest aus, führt eine Rückwärtsschleife für optimale Effizienz aus, stellt sicher, dass die zufällige Auswahl vereinfacht wird (sie kann immer bei 0 beginnen) und überspringt dadurch das letzte Element.
Laufzeit des Algorithmus ist O(n)
. Notiz dass das Mischen an Ort und Stelle erfolgt. Wenn Sie also das ursprüngliche Array nicht ändern möchten, erstellen Sie zuerst eine Kopie davon mit .slice(0)
.
Mit dem neuen ES6 können wir zwei Variablen gleichzeitig zuweisen. Dies ist besonders praktisch, wenn wir die Werte zweier Variablen austauschen möchten, da wir dies in einer Codezeile tun können. Hier ist eine kürzere Form derselben Funktion, die diese Funktion verwendet.
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
Die Implementierung in dieser Antwort bevorzugt das untere Ende des Arrays. Auf die harte Tour herausgefunden. Math.random() should not be multiplied with the loop counter + 1, but with
array.länge()`. Siehe Generieren zufälliger ganzer Zahlen in JavaScript in einem bestimmten Bereich? für eine sehr umfassende Erklärung.
– Marjan Venema
18. Dezember 2016 um 20:17 Uhr
@MarjanVenema Ich bin mir nicht sicher, ob du diesen Bereich immer noch beobachtest, aber diese Antwort ist richtig, und die Änderung, die Sie vorschlagen, führt tatsächlich zu Voreingenommenheit. Sehen blog.codinghorror.com/the-danger-of-naivete für eine schöne Beschreibung dieses Fehlers.
– Benutzer94559
11. März 2017 um 1:44 Uhr
Wiederholung des Kommentars von user94559 mit Referenzen en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle Das zu tauschende Element (j) sollte zwischen 0 und dem aktuellen Array-Index (i) liegen
– RedPandaCurios
19. Mai 2021 um 8:32 Uhr
Hier ist die gleiche Funktion, aber komprimiert: function shuffle(a){for(var j,i=a.length-1;i>0;i--){j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]]}}
– Ashleedawg
24. Oktober 2021 um 4:47 Uhr
Könnten wir das hier machen let i = array.length;
anstatt let i = array.length - 1;
in der for-Schleife und dann const j = Math.floor(Math.random() * i);
in der nächsten Zeile?
– Iwan Milenkovic
21. Januar um 15:21 Uhr
Sehr schön. Dies ist das Schwartzsche Transformation in js.
– Mark Grimes
29. Juni 2018 um 10:43 Uhr
Dies ist aus mehreren Gründen die beste Antwort hier (für kurze Arrays). Für mich ist es wirklich nützlich, weil ich React im Jahr 2021 verwende, was am besten mit einem funktionalen Ansatz wie diesem funktioniert.
– Softwareentwickler
1. September 2021 um 13:43 Uhr
Da Sie eine Pfeilfunktion für einen einzelnen Parameter sind, ist value => ({ value, … genug. Vielen Dank für Ihre Antwort
– Daniel Uko
25. Januar um 22:38 Uhr
Danke @DanielUko – ich habe die Antwort aktualisiert.
– Überlicht
3. Februar um 12:42 Uhr
tot
Warnung!
Die Verwendung dieses Algorithmus ist nicht empfohlendenn es ist ineffizient und stark voreingenommen; Zeige Kommentare. Es wird hier für zukünftige Referenzen belassen, weil die Idee nicht so selten ist.
[1,2,3,4,5,6].sort( () => .5 - Math.random() );
Dies https://javascript.info/array-methods#shuffle-an-array Tutorial erklärt die Unterschiede direkt.
Downvoting, da dies nicht wirklich zufällig ist. Ich weiß nicht, warum es so viele Upvotes hat. Verwenden Sie diese Methode nicht. Sieht hübsch aus, ist aber nicht ganz korrekt. Hier sind die Ergebnisse nach 10.000 Iterationen, wie oft jede Zahl in Ihrem Array auf den Index trifft [0] (Die anderen Ergebnisse kann ich auch angeben): 1 = 29,19 %, 2 = 29,53 %, 3 = 20,06 %, 4 = 11,91 %, 5 = 5,99 %, 6 = 3,32 %
– radtad
13. November 2013 um 18:35 Uhr
Es ist in Ordnung, wenn Sie relativ kleine Arrays randomisieren müssen und sich nicht mit kryptografischen Dingen befassen müssen. Ich stimme dem vollkommen zu, wenn Sie mehr brauchen Zufälligkeit Sie müssen eine komplexere Lösung verwenden.
– tot
21. November 2013 um 0:37 Uhr
Es ist auch die am wenigsten effizienten aller verfügbaren Methoden.
– Brandstifter
17. Dezember 2013 um 14:21 Uhr
Das Problem ist, dass es nicht deterministisch ist, was zu falschen Ergebnissen führt (wenn 1 > 2 und 2 > 3, sollte 1 > 3 angegeben werden, aber dies garantiert dies nicht. Dies wird die Sortierung verwirren und das Ergebnis kommentieren von @radtad).
– Mats Lindh
10. September 2014 um 14:07 Uhr
Wichtige Lektüre: Ist es richtig, die JavaScript-Methode Array.sort() zum Mischen zu verwenden?
– Bergi
3. April 2015 um 20:48 Uhr
Käse
Man könnte (oder sollte) es als Prototyp von Array verwenden:
Von ChristopheD:
Array.prototype.shuffle = function() {
var i = this.length, j, temp;
if ( i == 0 ) return this;
while ( --i ) {
j = Math.floor( Math.random() * ( i + 1 ) );
temp = this[i];
this[i] = this[j];
this[j] = temp;
}
return this;
}
Downvoting, da dies nicht wirklich zufällig ist. Ich weiß nicht, warum es so viele Upvotes hat. Verwenden Sie diese Methode nicht. Sieht hübsch aus, ist aber nicht ganz korrekt. Hier sind die Ergebnisse nach 10.000 Iterationen, wie oft jede Zahl in Ihrem Array auf den Index trifft [0] (Die anderen Ergebnisse kann ich auch angeben): 1 = 29,19 %, 2 = 29,53 %, 3 = 20,06 %, 4 = 11,91 %, 5 = 5,99 %, 6 = 3,32 %
– radtad
13. November 2013 um 18:35 Uhr
Es ist in Ordnung, wenn Sie relativ kleine Arrays randomisieren müssen und sich nicht mit kryptografischen Dingen befassen müssen. Ich stimme dem vollkommen zu, wenn Sie mehr brauchen Zufälligkeit Sie müssen eine komplexere Lösung verwenden.
– tot
21. November 2013 um 0:37 Uhr
Es ist auch die am wenigsten effizienten aller verfügbaren Methoden.
– Brandstifter
17. Dezember 2013 um 14:21 Uhr
Das Problem ist, dass es nicht deterministisch ist, was zu falschen Ergebnissen führt (wenn 1 > 2 und 2 > 3, sollte 1 > 3 angegeben werden, aber dies garantiert dies nicht. Dies wird die Sortierung verwirren und das Ergebnis kommentieren von @radtad).
– Mats Lindh
10. September 2014 um 14:07 Uhr
Wichtige Lektüre: Ist es richtig, die JavaScript-Methode Array.sort() zum Mischen zu verwenden?
– Bergi
3. April 2015 um 20:48 Uhr
Hexacyanid
Verwenden Sie die Bibliothek underscore.js. Die Methode _.shuffle()
ist schön für diesen Fall. Hier ist ein Beispiel mit der Methode:
var _ = require("underscore");
var arr = [1,2,3,4,5,6];
// Testing _.shuffle
var testShuffle = function () {
var indexOne = 0;
var stObj = {
'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5
};
for (var i = 0; i < 1000; i++) {
arr = _.shuffle(arr);
indexOne = _.indexOf(arr, 1);
stObj[indexOne] ++;
}
console.log(stObj);
};
testShuffle();
Werfen Sie das einfach hierher, damit Sie visualisieren können, wie zufällig eine Shuffle-Funktion tatsächlich ist, mit diesem Visualizer, den Mike Bostock erstellt hat: bost.ocks.org/mike/shuffle/compare.html
– Aug
10. Dezember 2014 um 19:42 Uhr
@Blazemonger jsPref ist tot. Kannst du hier posten, was am schnellsten ist?
– eozzy
28. September 2016 um 1:06 Uhr
Wie wäre es damit?
arr1.sort(() => (Math.random() > .5) ? 1 : -1);
– yuval.bl
26. September 2018 um 17:18 Uhr
eine kurze Antwort wäre
a.sort(() => Math.random() - 0.5)
– Sabosuke
3. September 2021 um 18:52 Uhr
@TheVee siehe einige Zeilen oben, auf der gleichen Spezifikation: “Die Sortierreihenfolge ist implementierungsdefiniert, wenn … Wenn Comparefn nicht undefiniert ist und keine konsistente Vergleichsfunktion für die Elemente von Elementen ist”
– yuval.bl
11. November 2021 um 16:12 Uhr