Abrufen eines zufälligen Werts aus einem JavaScript-Array

794

Erwägen:

var myArray = ['January', 'February', 'March'];    

Wie kann ich mit JavaScript einen zufälligen Wert aus diesem Array auswählen?

Sarah
quelle

Antworten:

1481

Es ist ein einfacher Einzeiler

const randomElement = array[Math.floor(Math.random() * array.length)];

Beispiel

const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const randomMonth = months[Math.floor(Math.random() * months.length)];

console.log("random month =>", randomMonth);

Jacob Relkin
quelle
9
@SapphireSun das ist richtig. Beachten Sie den Math.floor(Math.random(...))Anruf, der abrundet.
Asche999
33
Ahh, ich habe etwas Neues gelernt. Ich habe den Fall besprochen, in dem es genau 1 entspricht, aber anscheinend (laut W3Schools) liegt Math.random zwischen 0 inklusive und 1 exklusiv. Mein Fehler.
SapphireSun
13
Ich könnte mich irren, aber ich erinnere mich, dass ich var rand = myArray[Math.random() * myArray.length>>0]etwas schneller war
vrugtehagel
6
Nur für den Fall, wenn Sie bereits lodash verwenden, können Sie _.sample (Array)
Gabriel Matusevich
2
Ich bevorzuge diese Variante:var rand = myArray[Math.random() * myArray.length | 0]
Nicolas
76

Wenn du schon hast Ihr Projekt Unterstriche oder Lodash enthält , können Sie diese verwenden _.sample.

// will return one item randomly from the array
_.sample(['January', 'February', 'March']);

Wenn Sie mehr als ein Element zufällig erhalten müssen, können Sie dies als zweites Argument im Unterstrich übergeben:

// will return two items randomly from the array using underscore
_.sample(['January', 'February', 'March'], 2);

oder verwenden Sie die _.sampleSizeMethode in lodash:

// will return two items randomly from the array using lodash
_.sampleSize(['January', 'February', 'March'], 2);
Brendan Nee
quelle
Bei Verwendung von Typoskript: Beachten Sie, dass der Rückgabetyp bei einem String-Array "string | undefined" anstelle von "string" lautet.
Stephan Schielke
23

Prototyp-Methode

Wenn Sie vorhaben, häufig einen zufälligen Wert zu erhalten, möchten Sie möglicherweise eine Funktion dafür definieren.

Fügen Sie dies zunächst irgendwo in Ihren Code ein:

Array.prototype.sample = function(){
  return this[Math.floor(Math.random()*this.length)];
}

Jetzt:

[1,2,3,4].sample() //=> a random element

Code, der unter den Bedingungen der CC0 1.0-Lizenz öffentlich zugänglich ist .

Ben Aubin
quelle
Und das macht was?
Ken Sharp
3
@ KenSharp ermöglicht es Ihnen, .sample()jedes Array aufzurufen , um ein zufälliges Element zu erhalten
Ben Aubin
5
Das Erweitern nativer Objekttypen sollte vermieden werden. Ich habe meine Antwort gelöscht, da sie viel positiv bewertet wurde, aber schlechte Praktiken gefördert hat. Weitere Informationen zu diesem Thema finden Sie beispielsweise unter stackoverflow.com/questions/14034180/… und eslint.org/docs/rules/no-extend-native
Markus Amalthea Magnuson
20

~~ist viel schneller als Math.Floor(), also wenn es um Leistungsoptimierung bei der Produktion von Ausgaben mit UI-Elementen geht, ~~gewinnt das Spiel. MEHR INFO

var rand = myArray[~~(Math.random() * myArray.length)];

Wenn Sie jedoch wissen, dass das Array Millionen von Elementen enthalten wird, sollten Sie zwischen Bitwise Operator und Bitwise Operator Math.Floor()mit großen Zahlen ein seltsames Verhalten erzielen. Siehe das folgende Beispiel, das mit der Ausgabe erklärt wurde. MEHR INFO

var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343
Ankur Soni
quelle
1
Link ist tot, aber interessanter Beitrag und ich werde diesen mehr als Math.floorjetzt verwenden :)
aabbccsmith
Die Verwendung des Operators "bitwise not" ist zwar schneller, aber nicht so lesbar. Sie müssen also auswählen, was für Sie wichtiger ist
Maciej Urbański,
16

Angenommen, Sie möchten ein zufälliges Element auswählen, das sich vom letzten Mal unterscheidet (nicht wirklich zufällig, aber dennoch eine häufige Anforderung) ...

Aufbauend auf der Antwort von @Markus können wir eine weitere Prototypfunktion hinzufügen:

Array.prototype.randomDiffElement = function(last) {
   if (this.length == 0) {
      return;
   } else if (this.length == 1) {
      return this[0];
   } else {
      var num = 0;
      do {
         num = Math.floor(Math.random() * this.length);
      } while (this[num] == last);
      return this[num];
   }
}

Und so umsetzen:

var myRandomDiffElement = myArray.randomDiffElement(lastRandomElement)
CrazyTim
quelle
11

Wenn Sie feste Werte haben (z. B. eine Monatsnamenliste) und eine einzeilige Lösung wünschen

var result = ['January', 'February', 'March'][Math.floor(Math.random() * 3)]

Der zweite Teil des Arrays ist eine Zugriffsoperation wie unter Warum ist [5,6,8,7] [1,2] = 8 in JavaScript beschrieben?

IG Pascual
quelle
2
Ein solcher Code ist eine schlechte und schädliche Praxis. Es sollte niemals in der Produktion verwendet werden. Es hat eine geringe Lesbarkeit und eine fest codierte Array-Länge. Die Person, die die Array-Eingabe ändert, vergisst möglicherweise, die am Ende fest codierte Länge zu bearbeiten.
Möwe
@Seagull OP hat nie nach einer bestimmten Umgebung gefragt. Auch dieser Kommentar ist bedeutungslos, da er auf fast alle Antworten in dieser Frage angewendet werden könnte;)
IG Pascual
Die meisten Menschen kommen jedoch über die Google-Suche zu dieser Frage und verwenden die Lösung möglicherweise in anderen Szenarien als dem ursprünglichen OP.
Möwe
@Seagull Haha, die Leute können frei entscheiden, welchen Ansatz sie verwenden möchten. Ich bin nicht die FAQ für saubere Code-Richtlinien!
IG Pascual
10

Die kürzeste Version:

var myArray = ['January', 'February', 'March']; 
var rand = myArray[(Math.random() * myArray.length) | 0]
Foxiris
quelle
Was macht | 0das
Ken Sharp
2
Float wird wie bei Math.floor in Int umgewandelt.
Foxiris
4
@KenSharp | 0selbst ist eine bitweise Operation, die nichts bewirkt, aber in Javascript werden Floats vor jeder bitweisen Operation in Ints konvertiert . Es ist also so etwas wie, dass + ''man eigentlich nichts macht, sondern Dinge in Strings konvertieren kann.
Dshepherd
Es ist nicht dasselbe wie, Math.flooraber es ist das Richtige, was hier zu tun ist. Es ist ein Operator, also schneller als Math.floorwenn nur, weil zu jeder Zeit während der Ausführung Code ausgeführt werden kann Math.floor = someOtherFunctionund sie dies nicht für '|' tun können. Auf der anderen Seite wie Math.floorund |verschieden try Math.floor(-1.5)vs -1.5 | 0. Übrigens brauchen Sie die Klammern nicht. |hat eine sehr niedrige Priorität.
Gman
7

Wenn Sie es wie die Lösung von Pascual in eine Zeile schreiben möchten, besteht eine andere Lösung darin, es mit der Suchfunktion von ES6 zu schreiben (basierend auf der Tatsache, dass die Wahrscheinlichkeit einer zufälligen Auswahl eines Elements zufällig nist 1/n):

var item = ['A', 'B', 'C', 'D'].find((_, i, ar) => Math.random() < 1 / (ar.length - i));
console.log(item);

Verwenden Sie diesen Ansatz zu Testzwecken und wenn es einen guten Grund gibt, das Array nicht nur in einer separaten Variablen zu speichern. Andernfalls sind die anderen Antworten ( floor(random()*lengthund die Verwendung einer separaten Funktion) Ihr Weg.

Stephan
quelle
Sehr originelle Lösung. Gut gemacht! Übrigens die einzige echte und dynamische Einzeilerlösung hier.
Slavik Meltser
7

Faker.js verfügt über viele Dienstprogrammfunktionen zum Generieren von zufälligen Testdaten. Dies ist eine gute Option im Kontext einer Testsuite:

const Faker = require('faker');
Faker.random.arrayElement(['January', 'February', 'March']);

Wie von Kommentatoren erwähnt, sollten Sie diese Bibliothek im Produktionscode im Allgemeinen nicht verwenden.

Nathan
quelle
8
Für ein einfaches Problem wie dieses ist das Hinzufügen einer Abhängigkeit für eine gesamte Bibliothek nicht erforderlich und trägt zum Aufblähen des Codes bei. Wenn überhaupt, können Sie möglicherweise die tatsächliche Methode empfehlen, aus Fakerder ein zufälliges Array-Element ausgewählt wird.
Pixxl
1
"Einfaches Problem" wie dieses wird normalerweise von Bibliotheken gelöst, die eine einfache Lösung für ein Problem bieten, mit dem bereits Hunderte von Personen konfrontiert waren. Diese Bibliotheken sind normalerweise robust und gut getestet und behandeln verschiedene Einschränkungen, die wir nicht erneut implementieren möchten. In der Regel würde ich empfehlen, eine Bibliothek zu verwenden.
Smonff
Dann sollten Sie nur diese eine Methode aus der Bibliothek kopieren und in eine Utils-Datei einfügen
Rick Bross
Der Rat, dass Bibliotheken beim Versand an einen Webbrowser auf Kosten / Nutzen-WRT-Seitengewicht geprüft werden sollten, ist ein guter Rat, und ich stimme voll und ganz zu, dass der Versand von Faker.js an einen Browser lächerlich wäre. In der Frage wird jedoch nicht erwähnt, welche JS-Laufzeit verwendet wird. Für eine NodeJS-basierte Laufzeit sind stärkere Abhängigkeiten durchaus sinnvoll, was der Fall ist, wenn ich Faker.js verwende - in Cucumber JS-Testsuiten.
Nathan
6

Das Bearbeiten des Array-Prototyps kann schädlich sein. Hier ist es eine einfache Funktion, die Arbeit zu erledigen.

function getArrayRandomElement (arr) {
  if (arr && arr.length) {
    return arr[Math.floor(Math.random() * arr.length)];
  }
  // The undefined will be returned if the empty array was passed
}

Verwendungszweck:

// Example 1
var item = getArrayRandomElement(['January', 'February', 'March']);

// Example 2
var myArray = ['January', 'February', 'March'];
var item = getArrayRandomElement(myArray);
Möwe
quelle
3

Rekursive, eigenständige Funktion, die eine beliebige Anzahl von Elementen zurückgeben kann (identisch mit lodash.sampleSize ):

function getRandomElementsFromArray(array, numberOfRandomElementsToExtract = 1) {
    const elements = [];

    function getRandomElement(arr) {
        if (elements.length < numberOfRandomElementsToExtract) {
            const index = Math.floor(Math.random() * arr.length)
            const element = arr.splice(index, 1)[0];

            elements.push(element)

            return getRandomElement(arr)
        } else {
            return elements
        }
    }

    return getRandomElement([...array])
}
dwilt
quelle
2

Verwenden Sie, um ein kryptostarkes Formulararray für zufällige Elemente zu erhalten

let rndItem = a=> a[rnd()*a.length|0];
let rnd = ()=> crypto.getRandomValues(new Uint32Array(1))[0]/2**32;

var myArray = ['January', 'February', 'March'];

console.log( rndItem(myArray) )

Kamil Kiełczewski
quelle
1

Dies ähnelt der Lösung von @Jacob Relkin, ist jedoch allgemeiner als diese:

Dies ist ES2015:

const randomChoice = arr => {
    const randIndex = Math.floor(Math.random() * arr.length);
    return arr[randIndex];
};

Der Code wählt eine Zufallszahl zwischen 0 und der Länge des Arrays aus und gibt dann das Element an diesem Index zurück.

Max Heiber
quelle
1

var item = myArray[Math.floor(Math.random()*myArray.length)];

oder gleichwertige kürzere Version:

var item = myArray[(Math.random()*myArray.length)|0];

Beispielcode:

var myArray = ['January', 'February', 'March'];    
var item = myArray[(Math.random()*myArray.length)|0];
console.log('item:', item);

Pavel P.
quelle
1

Einfache Funktion:

var myArray = ['January', 'February', 'March'];
function random(array) {
     return array[Math.floor(Math.random() * array.length)]
}
random(myArray);

ODER

var myArray = ['January', 'February', 'March'];
function random() {
     return myArray[Math.floor(Math.random() * myArray.length)]
}
random();

ODER

var myArray = ['January', 'February', 'March'];
function random() {
     return myArray[Math.floor(Math.random() * myArray.length)]
}
random();
Dhakshith
quelle
Es ist besser, die Variable myArrayy in Ihrer Funktion festzulegen, um den globalen Namespace nicht zu verschmutzen.
Neil Meyer
0

Meiner Meinung nach ist es besser, als mit Prototypen herumzuspielen oder sie rechtzeitig zu deklarieren, sie lieber einem Fenster auszusetzen:

window.choice = function() {
  if (!this.length || this.length == 0) return;
  if (this.length == 1) return this[0];
  return this[Math.floor(Math.random()*this.length)];
}

Jetzt überall in Ihrer App nennen Sie es wie folgt:

var rand = window.choice.call(array)

Auf diese Weise können Sie die for(x in array)Schleife weiterhin ordnungsgemäß verwenden

Frankies
quelle
1
Ich war nicht hier, als jemand es herabgestimmt hat, und ich habe es nicht herabgestimmt, aber ich vermute, dass das Aussetzen gegenüber einem Fenster im Grunde genommen eine globale Variable deklariert. Siehe: stackoverflow.com/questions/2613310/…
Chris
1
Sie sollten niemals for...inauf Arrays oder allgemein verwenden. Sie laufen Gefahr, die Prototypenkette zu durchlaufen. Es ist auch für alle Eigenschaften eines Objekts gedacht, nicht für alle Indizes in einem Array. Wenn Sie einen Iterator für ein Array verwenden möchten, verwenden Sie for (var i = 0; i < foo.length; i++){}. Verwenden Sie Array.prototype.forEachstattdessen noch besser so etwas .
Robert
1
Ich bevorzuge dies nicht, weil es den globalen Geltungsbereich verschmutzt. Man könnte sagen, dass dies der einzige ist, der dort ist, aber es wird Gewohnheiten geben, diese gute Praxis zu verletzen.
Jekk
0

Ich habe einen Weg gefunden, um die Komplikationen der Top-Antwort zu umgehen, indem ich die Variable rand mit einer anderen Variablen verkettet habe, mit der diese Nummer im Aufruf von myArray []; angezeigt werden kann. Durch Löschen des neu erstellten Arrays und Herumspielen mit seinen Komplikationen habe ich eine funktionierende Lösung gefunden:

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>

var myArray = ['January', 'February', 'March', 'April', 'May'];    

var rand = Math.floor(Math.random() * myArray.length);

var concat = myArray[rand];

function random() {
   document.getElementById("demo").innerHTML = (concat);
}
</script>

<button onClick="random();">
Working Random Array generator
</button>

</body>
</html>
FaverosGema
quelle
Ich bin verwirrt, warum concatsich hier jemals etwas ändert ... randomselbst ändert es nicht und nichts anderes wird mehr als einmal aufgerufen ...
BalinKingOfMoria CMs wieder herstellen
1
Diese Lösung ist nicht ganz sinnvoll. Warum erstellen Sie eine Variable namens concat?
Superluminary
0

static generateMonth() { 
const theDate = ['January', 'February', 'March']; 
const randomNumber = Math.floor(Math.random()*3);
return theDate[randomNumber];
};

Wenn Sie eine Konstantenvariable für das Array festlegen, haben Sie eine weitere Konstante, die zufällig zwischen den drei Objekten im Array auswählt, und die Funktion gibt dann einfach die Ergebnisse zurück.

Neil Meyer
quelle
-1

Ein generischer Weg, um zufällige Elemente zu erhalten:

let some_array = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
let months = random_elems(some_array, 3);

console.log(months);

function random_elems(arr, count) {
  let len = arr.length;
  let lookup = {};
  let tmp = [];

  if (count > len)
    count = len;

  for (let i = 0; i < count; i++) {
    let index;
    do {
      index = ~~(Math.random() * len);
    } while (index in lookup);
    lookup[index] = null;
    tmp.push(arr[index]);
  }

  return tmp;
}

Rafael
quelle
-1

randojs macht dies etwas einfacher und lesbarer:

console.log( rando(['January', 'February', 'March']).value );
<script src="https://randojs.com/1.0.0.js"></script>

Aaron Plocharczyk
quelle
1
Nur neugierig: Warum die Downvotes?
Leponzo
1
Einige Leute sind kein Fan davon, in Bibliotheken nach Code zu suchen, den sie selbst schreiben könnten, selbst wenn dies die Dinge schneller und lesbarer machen würde. Wenn die Bibliothek aus irgendeinem Grund ausfällt, weist Ihre Website jetzt einen Fehler auf. randojs geht nicht unter, aber das wissen sie nicht, weil es nicht so bekannt ist wie Bibliotheken wie jQuery zum Beispiel
Aaron Plocharczyk
-2

Hier ist ein Beispiel dafür:

$scope.ctx.skills = data.result.skills;
    $scope.praiseTextArray = [
    "Hooray",
    "You\'re ready to move to a new skill", 
    "Yahoo! You completed a problem", 
    "You\'re doing great",  
    "You succeeded", 
    "That was a brave effort trying new problems", 
    "Your brain was working hard",
    "All your hard work is paying off",
    "Very nice job!, Let\'s see what you can do next",
    "Well done",
    "That was excellent work",
    "Awesome job",
    "You must feel good about doing such a great job",
    "Right on",
    "Great thinking",
    "Wonderful work",
    "You were right on top of that one",
    "Beautiful job",
    "Way to go",
    "Sensational effort"
  ];

  $scope.praiseTextWord = $scope.praiseTextArray[Math.floor(Math.random()*$scope.praiseTextArray.length)];
varun
quelle
-2

eine andere einfache Methode:

var myArray = ['keke','keko','cano','halo','zirto'];

var randomValue = myArray[Math.round((Math.random()*1000))%myArray.length];
Kamuran Sönecek
quelle
-3

Erstellen Sie einen zufälligen Wert und übergeben Sie ihn an das Array

Bitte versuchen Sie folgenden Code ..

//For Search textbox random value
var myPlaceHolderArray = ['Hotels in New York...', 'Hotels in San Francisco...', 'Hotels Near Disney World...', 'Hotels in Atlanta...'];
var rand = Math.floor(Math.random() * myPlaceHolderArray.length);
var Placeholdervalue = myPlaceHolderArray[rand];

alert(Placeholdervalue);
Jignesh Darji
quelle
5
Diese Antwort verwendet dieselbe Lösung wie die bereits akzeptierte Antwort. Sie sollten es unterlassen, dieselbe Lösung zweimal hinzuzufügen, und stattdessen nur mögliche andere Alternativen ansprechen, die mehr zur Konversation beitragen würden.
Pixxl