# Array auf "Duplikate" überprüfen



## Oskar.p (21. Feb 2021)

Hallo,
ich habe ein Problem mit einem Script. Ich will mit Hilfe eines Script 6 zufällig generierte Zahlen ausgeben (Ich will sozusagen Lottozahlen ausgeben). Da aber auch in Lotto eine Zahl nicht doppelt vorkommt, will ich den Array auf Duplikate überprüfen und diese dann löschen, oder eine neue Zahl generieren. Nun, da ich ein absoluter Anfänger in dem Bereich bin, suche ich mir jetzt hier Hilfe. In HTML habe ich bereits eine Tabelle erstellt, die die Ergebnisse tabellarisch ausgibt, deshalb auch die 6 getElementByIds (vllt lässt sich dieses noch verkürzen)
*Aber* das Script funktioniert nicht...
Zur info:
-die Funktion generateRandom habe ich schon eingebunden.
-rdmOpt bedeutet random Output
-kann auch sein das hier offensichtliche Fehler vorliegen (Anfänger halt  )



```
function generateOutput()
{
    var output = new ArrayList(6);
   
    for (var a = 0 ; a < output.length ;a++)  //könnte man hier auch output.size nehmen?
    {
        var rand = generateRandom(49);
        if(output.contains(rand))
            {
                a = a -1;
            }
            else
            {
                output.add(rand);
            }

    }

    document.getElementById("rdmOpt1").innerHTML = output[1]; //vllt kann man dieses hier kürzen
    document.getElementById("rdmOpt2").innerHTML = output[2];
    document.getElementById("rdmOpt3").innerHTML = output[3];
    document.getElementById("rdmOpt4").innerHTML = output[4];
    document.getElementById("rdmOpt5").innerHTML = output[5];
    document.getElementById("rdmOpt6").innerHTML = output[6];
}

    document.getElementByID("optBtn").addEventListener(click, function()
    {
        generateOutput();
    }
    );
```


----------



## Barista (22. Feb 2021)

Arrays in Javascript sind eigentlich assoziative Arrays, also wie Maps in Java.

Du kannst also einfach ein Array mit der zu prüfenden Zahl als Index und mit Boolean True befüllen.

Zum Abfragen prüfst Du den Ergebnistyp, wie in Javascript üblich (Ich müsste das erst nachschlagen).


----------



## thecain (22. Feb 2021)

Ähmm... Nein. In Javascript gibts es keine assoziativen Arrays, nur Objekte.


----------



## mihe7 (22. Feb 2021)

Oskar.p hat gesagt.:


> *Aber* das Script funktioniert nicht...


Was genau funktioniert nicht?

In JavaScript gibt es keine ArrayList. Du kannst `var output=Array(6);` verwenden, dann push statt add und indexOf statt contains, wobei indexOf -1 liefert, falls das gesuchte Element nicht im Array enthalten ist.

Allgemein würde ich sagen, dass Du mit einer Variante von Knuths shuffle näher am echten Lotto wärst. Das kannst Du Dir mal als Zusatzaufgabe aufheben.


----------



## M.L. (22. Feb 2021)

So etwas wie ein "Set" oder Prüfung auf "unique values" gibt es auch unter JavaScript: https://www.geeksforgeeks.org/how-to-get-all-unique-values-remove-duplicates-in-a-javascript-array/  (Zahlen statt Strings einsetzen und ausprobieren)


----------



## Oskar.p (22. Feb 2021)

Oh okey, dann habe ich es ja komplett versagt , also wie gesagt bin halt ein Anfänger, werde dem Set-Befehl nachgehen und das mit dem IndexOf versuchen.


----------



## mrBrown (22. Feb 2021)

thecain hat gesagt.:


> Ähmm... Nein. In Javascript gibts es keine assoziativen Arrays, nur Objekte.


Es gibt Maps, die sind keine "normalen" Objekte 



M.L. hat gesagt.:


> So etwas wie ein "Set"


Treffenderweise heißt es sogar auch "Set"


----------



## Oskar.p (22. Feb 2021)

Also ich habe den Code jetzt abgeändert, sodass er die Zahlen (auch doppelte --> soll er aber nicht) ausgibt:

```
function generateOutput()
{
    var output = [];
    output.length = 7
    for (var a = 0 ; a < output.length ;a++)
    {
        output[a] = generateRandom(49);
    }

    document.getElementById("rdmOpt1").innerHTML = output[1];
    document.getElementById("rdmOpt2").innerHTML = output[2];
    document.getElementById("rdmOpt3").innerHTML = output[3];
    document.getElementById("rdmOpt4").innerHTML = output[4];
    document.getElementById("rdmOpt5").innerHTML = output[5];
    document.getElementById("rdmOpt6").innerHTML = output[6];
}

    document.getElementByID("optBtn").addEventListener(click, function()
    {
        generateOutput();
    }
    );
```

Ich versuche es irgendwie mit dem Set-Befehl, habe nur wiegesagt nicht soviel Ahnung.


----------



## M.L. (22. Feb 2021)

Weiterhin muss man sich nicht auf die in PHP gelieferte random-Funktionalität verlassen (könnte ja sein, dass doch eine oder mehrere Zahlen mehrfach auftreten und man gerade deswegen mehr als 6 Anläufe einkalkulieren darf), Stichwort linearer Kongruenzoperator (mit modulo 50). Mit geeigneten Startwerten könnte auch die Anwendung von Set entfallen...


----------



## Oskar.p (22. Feb 2021)

Ich hab den Code nochmal abgeändert nur leider gibt dieser anstatt die Zahlen immer ein undefined aus:

```
function generateOutput()
{
    var output = [];
    var set = new Set(output);
    output.length = 7;
    
    for (var a = 0 ; a < output.length ;a++)
    {
        var rand =  generateRandom(49);
        if(set.has(rand))
        {
            a--;
        }
        else
        {
            set.add(rand);
        }
    }

    document.getElementById("rdmOpt1").innerHTML = output[1];
    document.getElementById("rdmOpt2").innerHTML = output[2];
    document.getElementById("rdmOpt3").innerHTML = output[3];
    document.getElementById("rdmOpt4").innerHTML = output[4];
    document.getElementById("rdmOpt5").innerHTML = output[5];
    document.getElementById("rdmOpt6").innerHTML = output[6];
}

    document.getElementByID("optBtn").addEventListener(click, function()
    {
        generateOutput();
    }
    );
```


----------



## mihe7 (22. Feb 2021)

Oskar.p hat gesagt.:


> Ich hab den Code nochmal abgeändert


Die Idee beim Set ist, dass dieses jedes Element nur einmal enthalten kann.


----------



## mrBrown (22. Feb 2021)

M.L. hat gesagt.:


> Weiterhin muss man sich nicht auf die in PHP gelieferte random-Funktionalität verlassen


Das muss man ganz generell nicht, wenn man JavaScript benutzt.


----------



## Oskar.p (22. Feb 2021)

Was kann ich jetzt bei meinem Code ändern, sodass er funktioniert?


----------



## mihe7 (22. Feb 2021)

Du musst lediglich so lange Zufallszahlen zum Set hinzufügen, bis dieses die gewünschte Größe erreicht hat.


----------



## Oskar.p (22. Feb 2021)

Also ich mache irgendwas falsch, bei mir erhalte ich immer ein undefined.


----------



## mihe7 (22. Feb 2021)

```
var output = new Set();
while (output.size < 6) {
    output.add(generateRandom(49));
}
```


----------



## Oskar.p (22. Feb 2021)

Oh .. ,okey doch einfach


----------



## Oskar.p (22. Feb 2021)

und wie könnte ich diesen output mit einem andern input vergleichen, nach dem selben Prinzip? Also mein Ziel ist es Zahlen zu generieren und diese dann mit der Eingabe zu vergleichen, geht dies mit .has?


----------



## mihe7 (22. Feb 2021)

Ja, mit .has kannst Du prüfen, ob das Set ein bestimmtes Element enthält.


----------



## Oskar.p (22. Feb 2021)

Wie könnte ich die gespeicherten Daten ausgeben, also eines Sets. Muss ich dafür ein Array erstellen?


----------



## Oskar.p (22. Feb 2021)

Also ich habe das mit der While-Schleife versucht und nichts... (muss an der Ausgabe liegen)


----------



## Oskar.p (22. Feb 2021)

Mache ich etwas mit der Ausgabe falsch? Es kommt immer ein undefined.

```
function generateOutput()
{
 
    var set = new Set();
    while(set.size < 6)
    {
        set.add(generateRandom(49));
    }
   

    document.getElementById("rdmOpt1").innerHTML = set[1];
    document.getElementById("rdmOpt2").innerHTML = set[2];
    document.getElementById("rdmOpt3").innerHTML = set[3];
    document.getElementById("rdmOpt4").innerHTML = set[4];
    document.getElementById("rdmOpt5").innerHTML = set[5];
    document.getElementById("rdmOpt6").innerHTML = set[6];
}

    document.getElementByID("optBtn").addEventListener(click, function()
    {
        generateOutput();
    }
    );
```


----------



## mihe7 (22. Feb 2021)

Oskar.p hat gesagt.:


> Mache ich etwas mit der Ausgabe falsch?


Ja, ein Set ist kein Array.


----------



## Oskar.p (22. Feb 2021)

Wie soll ich dass richtig ausgeben, tut mir leid wenn ich dauerhaft frage, leider habe ich halt nicht so viel Ahnung.

```
function generateOutput()
{
    var output = [set];
    var set = new Set();
    while(set.size < 6)
    {
        set.add(generateRandom(49));
    } 
    

    document.getElementById("rdmOpt1").innerHTML = output[1];
    document.getElementById("rdmOpt2").innerHTML = output[2];
    document.getElementById("rdmOpt3").innerHTML = output[3];
    document.getElementById("rdmOpt4").innerHTML = output[4];
    document.getElementById("rdmOpt5").innerHTML = output[5];
    document.getElementById("rdmOpt6").innerHTML = output[6];
}

    document.getElementByID("optBtn").addEventListener(click, function()
    {
        generateOutput();
    }
    );
```


----------



## mihe7 (22. Feb 2021)

Du könntest z. B. ein Array aus dem Set erzeugen:

```
var arr = Array.from(output)
```


----------



## M.L. (22. Feb 2021)

Wie sieht eigentlich das aktuelle Projekt aus ? In der js-Funktion von #24 scheint 
	
	
	
	





```
document.getElementByID("optBtn").addEventListener(click, function()
```
  mit ByI*d *und *"*click*" *besser zu sein


----------



## Oskar.p (22. Feb 2021)

Das Projekt soll so aussehen: Du erhälts auf einer Website eine Tabelle , in der du 6 Tipps einträgst diese werden nun mit den Zufallsgenerierten ZAhlen verglichen und dementsprechend ausgegeben. Jetzt versuche ich erst mal das Problem zu lösen, dass keine zufällig generierten Zahlen erzeugt werden. Der "optBtn" ist ein Button der die Funktion ausführen soll.


----------



## Oskar.p (22. Feb 2021)

> Du könntest z. B. ein Array aus dem Set erzeugen:


Nun sieht das Programm so aus und funktioniert immer noch nicht:

```
function generateOutput()
{
    var arr = Array.from(output);
    var output = new Set();
    while(output.size < 6)
    {
        output.add(generateRandom(49));
    } 
    

    document.getElementById("rdmOpt1").innerHTML = arr[1];
    document.getElementById("rdmOpt2").innerHTML = arr[2];
    document.getElementById("rdmOpt3").innerHTML = arr[3];
    document.getElementById("rdmOpt4").innerHTML = arr[4];
    document.getElementById("rdmOpt5").innerHTML = arr[5];
    document.getElementById("rdmOpt6").innerHTML = arr[6];
}

    document.getElementById("optBtn").addEventListener(click, function()
    {
        generateOutput();
    }
    );
```


----------



## mrBrown (22. Feb 2021)

Oskar.p hat gesagt.:


> Jetzt versuche ich erst mal das Problem zu lösen, dass keine zufällig generierten Zahlen erzeugt werden. Der "optBtn" ist ein Button der die Funktion ausführen soll.



Tipp hast du doch schon bekommen: 


M.L. hat gesagt.:


> In der js-Funktion von #24 scheint
> 
> 
> 
> ...



(Das war auch mit "aussehen des Projekts" gemeint)


----------



## mrBrown (22. Feb 2021)

Oskar.p hat gesagt.:


> Nun sieht das Programm so aus und funktioniert immer noch nicht:


Zeile 5 sollte hinter die Schleife gezogen werden.


----------



## Oskar.p (22. Feb 2021)

Habe es geändert und es funktioniert leider immer noch nicht.


----------



## mrBrown (22. Feb 2021)

Und Arrays starten bei 0, nicht bei 1.


----------



## Oskar.p (22. Feb 2021)

L

```
function generateOutput()
{
    var arr = Array.from(output);
    while(output.size < 6)
    {
        var output = new Set();
        output.add(generateRandom(49));
    } 
    
    

    document.getElementById("rdmOpt1").innerHTML = arr[0];
    document.getElementById("rdmOpt2").innerHTML = arr[1];
    document.getElementById("rdmOpt3").innerHTML = arr[2];
    document.getElementById("rdmOpt4").innerHTML = arr[3];
    document.getElementById("rdmOpt5").innerHTML = arr[4];
    document.getElementById("rdmOpt6").innerHTML = arr[5];
}

    document.getElementById("optBtn").addEventListener("click", function()
    {
        generateOutput();
    }
    );
```
eider geht es immer noch nicht und ich konnte die Zahlen bereits schon ausgeben, leider auch doppelte, weshalb ich Set benutzt habe und seit dem funktioniert gar nichts :/


----------



## mrBrown (22. Feb 2021)

Die ersten Zeilen ergeben ja jetzt noch weniger Sinn als vorher 😅

Zeile 3: du erzeugst ein neues Array aus etwas nicht existierendem. arr ist dann ein leeres Array.
Zeile 4: du iterierst solange  output.size < 6 ist, output ist allerdings noch gar nicht existent – also greifst du auf site von undefined zu (da sollte der browser schon einen Fehler schmeißen)
Zeile 5: du erstellst in jedem Zeilendurchlauf ein neues Set, und schmeißt damit natürlich auch das vorherige und dessen Inhalt weg.


Versuch die ersten Zeilen noch mal selbst:

Du musst erst ein (leeres) Set erstellen. Dieses dann solange füllen, bis es 6 Werte enthält (die dann garantiert verschieden sind). Aus dem Set mit dann 6 Werten erzeugst du danach das Array.


----------



## Oskar.p (23. Feb 2021)

Okey, habe immer noch einen Fehler 😅

```
function generateOutput()
{
   
    var output =new Set();
    while(output.size < 6)
    {
        output.add(generateRandom(49));
    }
    var arr = Array.from(output);
   
   

    document.getElementById("rdmOpt1").innerHTML = arr[0];
    document.getElementById("rdmOpt2").innerHTML = arr[1];
    document.getElementById("rdmOpt3").innerHTML = arr[2];
    document.getElementById("rdmOpt4").innerHTML = arr[3];
    document.getElementById("rdmOpt5").innerHTML = arr[4];
    document.getElementById("rdmOpt6").innerHTML = arr[5];
}

    document.getElementById("optBtn").addEventListener("click", function()
    {
        generateOutput();
    }
    );
```


----------



## mihe7 (23. Feb 2021)

Oskar.p hat gesagt.:


> Okey, habe immer noch einen Fehler 😅


Du darfst ruhig dazuschreiben, welchen


----------



## Oskar.p (23. Feb 2021)

Das ist es ja, es wird immer noch nichts ausgegeben.


----------



## M.L. (23. Feb 2021)

Oskar.p hat gesagt.:


> immer noch nichts ausgegeben


Statt einer rein verbalen Beschreibung war gemeint, dass jemand Drittes das (aktuelle) Projekt nachstellen und Veränderungen vornehmen kann. Z.B.: 





> So sieht lotto.html aus:
> 
> 
> 
> ...


   Oder als (gezippten) Anhang, via repl.it / gist-Link (aktuelles YT-Video von D. Tielke )...


----------



## Oskar.p (23. Feb 2021)

Okey, hier ist nun mein Projekt:

```
<!Doctype HTML>
  <head>
    <title>Casino</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=0.1">
    <link rel="icon" href="src/Diamond.png"> //einfach nur ein Icon für die Website
    <link rel="stylesheet" href="style.css" type="text/css">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300&display=swap" rel="stylesheet">
    <script  src="src/generateRandom.js"></script>
    <script  src="src/generateOutput.js"></script>
  </head>

  <body>
    <section>
      <table id="rdmOpt">
        <tr>  <th>1</th>  <th>2</th> <th>3</th> <th>4</th> <th>5</th> <th>6</th> </tr>
        <tr>  <th id="rdmOpt1"></th> <th id="rdmOpt2"></th> <th id="rdmOpt3"></th> <th id="rdmOpt4"></th> <th id="rdmOpt5"></th> <th id="rdmOpt6"></th> </tr>
      </table>
      <table id="rdmIpt">
        <tr>  <th>1</th>  <th>2</th> <th>3</th> <th>4</th> <th>5</th> <th>6</th> </tr>
        <tr>  <th><input id="rdmIpt1"></th> <th><input id="rdmIpt2"></th> <th><input id="rdmIpt3"></th> <th><input id="rdmIpt4"></th> <th><input id="rdmIpt5"></th> <th><input id="rdmIpt6"></th> </tr>
      </table>
      <button id="optBtn" >Generate</button>
    </section>
  </body>
```


```
body {
    background: rgb(88, 87, 87);
    font-family: 'Nunito', sans-serif;
    position: absolute;
    width: 100% auto;
    height: 100% auto;
}

input{
    width:1.1em;
}

#rdmOpt {
    border: white 0.2em solid;
    border-radius: 4px;
    color: white;
}

#rdmIpt {
    border: white 0.2em solid;
    border-radius: 4px;
    color: white;
}
```

[CODE lang="javascript" title="generateOutput"]function generateOutput()
{

    var output =  new Set();
    while(output.size < 6)
    {
        output.add(generateRandom(49));
    }
    var arr = Array.from(output);





    document.getElementById("rdmOpt1").innerHTML = arr[0];
    document.getElementById("rdmOpt2").innerHTML = arr[1];
    document.getElementById("rdmOpt3").innerHTML = arr[2];
    document.getElementById("rdmOpt4").innerHTML = arr[3];
    document.getElementById("rdmOpt5").innerHTML = arr[4];
    document.getElementById("rdmOpt6").innerHTML = arr[5];
}

    document.getElementById("optBtn").addEventListener("click", function()
    {
        generateOutput();
    }
    );[/CODE]

[CODE lang="javascript" title="generateRandom"]function generateRandom(maximum)
{
    return Math.floor(Math.random()*maximum + 1);
}[/CODE]


----------



## M.L. (23. Feb 2021)

Oskar.p hat gesagt.:


> mein Projekt


Die gute Nachricht zuerst: der Code funktioniert nach einer kleinen Umstellung
Die schlechte Nachricht: der "Trick" ist nicht offensichtlich (stand aber im Link zu SO aus dem anderen Thread )...
Man befördert die zwei Zeilen zum Inkludieren der .js-Dateien nach unten:

```
...
</section>
<script  src="src/generateRandom.js"></script>
    <script  src="src/generateOutput.js"></script>

  </body>
```
Mit Google Chrome könnte das nach Druck auf "Generate" dann so aussehen:


----------



## Oskar.p (23. Feb 2021)

Danke, es funktioniert dieses mal wirklich! Dennoch hätte ich eine Frage, uns war : Warum muss man die .js Dateien nach unten inkludieren? Weil ich würde noch ein Script schreiben, dass die werte in dem einem Set auf Duplikate im anderen überprüft (dass man richtig geraten hat).


----------



## M.L. (23. Feb 2021)

Oskar.p hat gesagt.:


> muss man


Man muss gar nichts. ABER: es kann passieren, dass die JavaScript-Codes vor dem Aufbauen der HTML-Seite ausgeführt werden und auf Werte zugreifen, die noch nicht bekannt sind. Den JS-Code als letztes auszuführen umgeht genau dieses Problem  ( "..because it executes before the DOM fully loads.")


----------



## mihe7 (23. Feb 2021)

M.L. hat gesagt.:


> Die schlechte Nachricht: der "Trick" ist nicht offensichtlich


Kann es sein, dass @Oskar.p die Entwicklertools des Browsers nicht nutzt? Da hätte ein Fehler in der Konsole auftauchen müssen...


----------



## thecain (23. Feb 2021)

Der Trick ist eigtl Standard. Oder man eartet auf DOMContentLoaded oder den korrekten ReadyState


----------



## Oskar.p (23. Feb 2021)

Okey, vielen Dank erstmal für die Hilfe!. Ich versuche jetzt erstmal den Input mit dem "Set" zu vergleichen.


----------



## Oskar.p (23. Feb 2021)

wenn ich die Werte von dem Input in einem Array speichern könnte ich dies folgendermaßen machen:

```
var input =[document.getElementById("rdmIpt1").value,
                document.getElementById("rdmIpt2").value,
                document.getElementById("rdmIpt3").value,
                document.getElementById("rdmIpt4").value,
                document.getElementById("rdmIpt5").value,
                document.getElementById("rdmIpt6").value,]
```


----------

