Sebastian Becker: Zufallsauswahl aus Array

Hallo,

ich möchte gerne eine Zufallsauswahl mit einer bestimmten Anzahl von Elementen eines JavaScript-Arrays anzeigen.

Meine bisherige Lösung (s.u.) ist mir eigentlich noch zu umständlich und sie funktioniert auch nur zum Teil, da das ursprüngliche Array nicht erhalten bleibt, obwohl ich in meiner Funktion mit einer Kopie derselben arbeite. Deshalb kann ich die Zufallsauswahl ohne Neuladen der Seite bislang nur ein einziges mal erzeugen.

Any ideas?

Danke für die Hilfe, Grüße aus Berlin,

Sebastian

<head>
<script>

var contentArray = new Array("fishfingers","Utah","mercurichrome","vespa","flouresce","spantangle","daedal","hogwarmer","spoot","maneouvre","pneumatic","basejumping","beanthrower","catgut","stormpie");

function randomContent(arr)
{
arr = contentArray;
alert(contentArray.length);
// remove random elements
while(arr.length>5) {
randy = Math.floor(Math.random()*arr.length);
arr.splice(randy,1)
}

contentOutput = "";
for(j=0;j<arr.length;j++) {
thisContent = arr[j];
contentOutput += thisContent + "\r";
}
document.forms[0].elements[0].value = contentOutput;
}

var randy = 0;

</script>

</head>

<body onLoad="randomContent(contentArray);">

<form action="javascript: randomContent(contentArray)">
<textarea cols="24" rows="10"></textarea>
<input value="Randomize" type="submit">
</form>

</body>

  1. Hi Sebastian,

    Meine bisherige Lösung (s.u.) ist mir eigentlich noch zu umständlich [...]

    Das ist sie in der Tat ;-) Es geht einfacher:

    function randomContent(arr) {  
      var rand  = Math.floor(Math.random() * arr.length);  
      return arr[rand];  
    }
    

    Verwende ich in ähnlicher Form in der Praxis, die Funktion gibt einen zufälligen Eintrag des Arrays zurück.

    Anwendungsbeispiele:

    // arr ist ein Array mit Informationen  
    alert(randomContent(arr));  
    document.getElementById('ausgabe').innerHTML = randomContent(arr);
    

    Viele Grüße aus Kanada,
      ~ Dennis.

    1. Hallo, Dennis,

      ich möchte aber _mehrere_ einzigartige (unique) zufällige Einträge des Arrays ausgeben ...

      Grüße,

      Sebastian

      1. Lieber Sebastian,

        ich möchte aber _mehrere_ einzigartige (unique) zufällige Einträge des Arrays ausgeben ...

        ...und was hindert Dich daran, diese Funktion mehrmals aufzurufen? Wenn Du die Ergebnisse vergleichst, dann kannst Du die Einzigartigkeit dadurch garantieren, dass Du Dir so oft von der Funktion ein Ergebnis geben lässt, bis Du Deine Anzahl an Ergebnissen voll hast.

        (ungetestet!)

        var anzahl = 7; // Diesen Wert könnte man auch zufällig gestalten...  
        var ergebnisse = new Array();  
        /* arr steht für Dein Array, in welchem die Daten stehen,  
           randomContent für die von Dennis vorgeschlagene Funktion! */  
        for (var i = 0; i < anzahl; i++) {  
            var einzigartig = false;  
            var versuch = null;  
            while (!einzigartig) {  
                versuch = randomContent(arr);  
                einzigartig = true;  
                // wirklich einzigartig?  
                for (var j = 0; j < ergebnisse.length; j++) {  
                    if (versuch == ergebnisse[j])  
                        einzigartig = false;  
                }  
            }  
            if (versuch != null)  
                ergebnisse[ergebnisse.length] = versuch;  
            /* sollte anzahl größer als die Anzahl an Elementen in arr sein,  
               dann haben wir hier eine Endlos-Schleife... */  
        }
        

        Liebe Grüße aus Ellwangen,

        Felix Riesterer.

      2. Hallo Sebastian,

        ich möchte aber _mehrere_ einzigartige (unique) zufällige Einträge des Arrays ausgeben ...

        du könntest das Array auch mischen und dann die ersten N Elemente nehmen. Sie hierzu http://forum.de.selfhtml.org/archiv/2006/12/t142119/#m924652.

        Gruß, Jürgen

        1. Tach.

          du könntest das Array auch mischen und dann die ersten N Elemente nehmen. Sie hierzu http://forum.de.selfhtml.org/archiv/2006/12/t142119/#m924652.

          Falls das Array sehr groß ist und nicht bei jedem Aufruf komplett gemischt werden soll, kann die angegebene Funktion auch leicht noch um Parameter erweitert werden, die den Bereich (Array-Indizes) angeben, der gemischt werden soll.

          --
          Once is a mistake, twice is jazz.
        2. Hallo, Jürgen,

          ich möchte aber _mehrere_ einzigartige (unique) zufällige Einträge des Arrays ausgeben ...

          du könntest das Array auch mischen und dann die ersten N Elemente nehmen. Sie hierzu http://forum.de.selfhtml.org/archiv/2006/12/t142119/#m924652.

          gute Idee, Danke! Meine Lösung auf Basis eines anderen Skripts steht unten.

          Grüße aus Berlin,

          Sebastian

          Trotzdem würde mich immer noch interessieren, warum bei dem ursprünglich geposteten Skript das Array verändert wurde ...

          <script>

          /**************************************
          Random Array Elements
          **************************************/

          function randomArrayElements(arr,num)
          {
          // shuffle array elements
          // based on code by Jonas Raoni Soares Silva (www.joninhas.ath.cx)
          for(var j,x,i=arr.length;i;j=parseInt(Math.random()*i),x=arr[--i],arr[i]=arr[j],arr[j]=x);
          // get first [num] elements
          if(num)var arr = arr.slice(0,num);
          return arr;
          }

          // test
          var arraytoshuffle = new Array;
          arraytoshuffle = ["A","B","C","D","E","F","G","H","I","J",0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
          document.write(randomArrayElements(arraytoshuffle,6));

          </script>

  2. Moin

    <head>
    <script>

    sinnvoll wäre <script type="text/javascript">

    var contentArray = new Array("fishfingers","Utah","mercurichrome","vespa","flouresce","spantangle","daedal","hogwarmer","spoot","maneouvre","pneumatic","basejumping","beanthrower","catgut","stormpie");

    function randomContent(arr)

    das Argument arr nutzt du gar nicht, also weglassen

    {
    arr = contentArray;

    hier definierst du es nämlich, aber als globale Variable, obwohl sie nur lokal gebraucht wird.
    Besser:
    var arr = contentArray;

    dann sollten Änderungen an der lokalen Variablen auch keine Folgeschäden beim globalen Array contentArray hinterlassen

    alert(contentArray.length);
    // remove random elements
    while(arr.length>5) {
    randy = Math.floor(Math.random()*arr.length);
    arr.splice(randy,1)
    }

    contentOutput = "";
    for(j=0;j<arr.length;j++) {
    thisContent = arr[j];
    contentOutput += thisContent + "\r";
    }
    document.forms[0].elements[0].value = contentOutput;
    }

    var randy = 0;

    </script>

    </head>

    <body onLoad="randomContent(contentArray);">

    lass dann hier auch das Argument weg

    <form action="javascript: randomContent(contentArray)">

    und hier, ebenso das Leerzeichen nach javascript:

    <textarea cols="24" rows="10"></textarea>
    <input value="Randomize" type="submit">
    </form>

    </body>

    Gruß
    rfb

    1. Hallo, rfb,

      Deine gut gemeinten Vorschläge hast Du nicht mal ausprobiert?!
      Sie funktionieren nämlich leider nicht ...

      arr = contentArray;

      ... hatte ich nur zum Testen benutzt und vor dem Posten wieder auszukommentieren vergessen. Es macht letztlich keinen Unterschied, ob ich das Array in der Funktion direkt auslese oder es als Parameter übergebe.

      Rätselhaft bleibt nach wie vor, warum sich der Inhalt des Arrays ändert, obwohl ich damit gar nichts anstelle. Außerdem wäre es schön eine Lösung zu finden, wie man das Ziel, eine Zufallsauswahl mehrerer Element aus einem Array zu erstellen, weniger umständlich erreichen kann ...

      Grüße,

      Sebastian

  3. <head>
    <script>

    Hier fehlt das type Attribut.

    var contentArray = new Array("fishfingers","Utah","mercurichrome","vespa","flouresce","spantangle","daedal","hogwarmer","spoot","maneouvre","pneumatic","basejumping","beanthrower","catgut","stormpie");

    function randomContent(arr)
    {
    arr = contentArray;

    Das ist Unsinn, einmal, weil du mdamit den Parameter arr überschreibst und dann, weil JS keine Objekte kopiert, sondern arr ist jetzt gleich contentArray, wenn du eine Kopie haben willst must du das "von Hand" machen.

    alert(contentArray.length);
    // remove random elements
    while(arr.length>5) {
    randy = Math.floor(Math.random()*arr.length);
    arr.splice(randy,1)
    }

    Du soltest globale Variabeln, wie in allen anderen Programmiersprachen auch,  vermieden und hier ist sie auch gar nicht nötig.

    contentOutput = "";
    for(j=0;j<arr.length;j++) {
    thisContent = arr[j];
    contentOutput += thisContent + "\r";
    }

    Das geht einfacher mit join:
    contentOutput = arr.join('\n');

    <form action="javascript: randomContent(contentArray)">

    Das ist Quark, nimm den submithandler:
    <form action="" onsubmit="randomContent()">

    Struppi.

    --
    Javascript ist toll (Perl auch!)