Mssmar: Werte eines Arrays auslesen und die redunanten entfernen

Hallo,

ich fülle dynamisch aus einem Array mit der folgenden Funktion einen Dropdownmenu:

  
function showModell() {  
 this.choosenCar = document.cars.aktAutomarke.options[document.cars.aktAutomarke.options.selectedIndex].value;  
  
 alert(choosenCar);  
 document.cars.autoModell.options.length=0;  
 for(i=0; i<autos.length; i++) {  
  if (autos[i][0] == choosenCar){  
      document.cars.autoModell.options[document.cars.autoModell.options.length] =  
      new Option(autos[i][1],autos[i][1]);  
  }  
 }  
  
}  
  

wie kann aber ich rausfinden, ob ein Wert aus dem zweiten Index des Arrays sich wiederholt, damit ich denn die redunanten Werte entferne.

z.B. wenn ich folgendermaßen aus dem Array unten den zweiten Wert auslese,

autos[i][1];

dann will ich in dem Dropdown nur die zwei Wete Clio Storia und Espace haben und nicht drei Mal Clio Storia und drei Mal Espace.

  
var autos = new Array  
(  
new Array('Renault','Clio Storia','1,2 5T'),  
new Array('Renault','Clio Storia','1,5 dCi 3T'),  
new Array('Renault','Clio Storia','1,5 dCi 5T'),  
new Array('Renault','Espace','1,9 dCi'),  
new Array('Renault','Espace','2,0 16V'),  
new Array('Renault','Espace','2,0 T')  
);  

Vielen Dank und Gruß
Messmar

  1. Moin!

    Allgemein kannst Du sowas mit assoziativen Arrays erledigen:

      
    var seen= new Array();  
      
    for (var i= liste.length; i--;) {  
      if ( 0 == seen[ liste[i] ]++ ) {  
        // Dieser Eintrag ist neu  
    // Hier also hinzufügen  
      }  
      else {  
        // Dieser Eintrag trat zum seen[ liste[i] ]ten Male auf  
      }  
    }  
    
    

    -- Skeeve

    1. Hallo,

        
      ...  
         if ( 0 == seen[ liste[i] ]++ ) {  
      ...  
      
      

      Wenn ich Dich hier richtig verstehe, dann sollte die 0 da oben innerhalb der If-Abfrage das erste Index/Element in die Liste.

      Aber hier wo ich Deinen Lösungsvorschlag versuche zu verwenden, erhalte ich beim zweiten alert(); gar nichts. D.h. der Fall mit der If-Abfrage
      tritt gar nicht auf oder ich habe hier was Du mit dem 0 tust falsch verstanden.

        
      function showModell() {  
       this.choosenCar = document.cars.aktAutomarke.options[document.cars.aktAutomarke.options.selectedIndex].value;  
        
       alert(choosenCar);  
       document.cars.autoModell.options.length=0;  
       for(i=0; i<autos.length; i++) {  
        if (autos[i][0] == choosenCar){  
         document.cars.autoModell.options[document.cars.autoModell.options.length] =  
            new Option(autos[i][1],autos[i][1]);  
        }  
       }  
        
       var seen = new Array();  
       this.choosenModell1 = document.cars.autoModell.options;  
       for (var k = choosenModell1.length; k--;) {  
         alert(choosenModell1[k]);  
         if (0 == seen[choosenModell1[k]]++) {  
           // Dieser Eintrag ist neu  
        alert("zweite alert mit dem neuen Wert: " + choosenModell1[k]);  
        // Hier also hinzufügen  
         }  
         else {  
          alert("Dieser Wert ist schon vorhanden: " + choosenModell1[k]);  
           // Dieser Eintrag trat zum seen[ liste[i] ]ten Male auf  
         }  
       }  
        
      }  
      
      
      1. Moin!

        Du hast das richtig verstanden und ich sollte testen, wenn ich Perl-Konzepte in JavaScript überfuhre :-( Entschuldige! Besser ist es, das richtig zu machen, und zwar so:

          
          if ( seen[ liste[i] ] ) {  
            // Dieser Eintrag trat schon auf  
            alert("Alt: "+liste[i]);  
          }  
          else {  
            // Dieser Eintrag ist neu  
            // Hier also hinzufügen  
            seen[ liste[i] ]= 1;  
            alert("Neu: "+liste[i]);  
          }  
        
        

        -- Skeeve

        1. Hallo,

          [...] Besser ist es, das richtig zu machen, und zwar so: [...]

          Ich habe meinen Code folgendermaßen angepasst, aber es zeigt in dem Fall nur einen Eintrag in die Liste. Irgendwo ist der Fehler, aber ich kann es leider nicht sehen:

          [code lang =javascript]
          function showModell() {
           this.choosenCar = document.cars.aktAutomarke.options[document.cars.aktAutomarke.options.selectedIndex].value;

          alert(choosenCar);
           document.cars.autoModell.options.length=0;

          var i;

          for(i=0; i<autos.length; i++) {
            test = autos[i][1];
            if (autos[i][0] == choosenCar){

          document.cars.autoModell.options[document.cars.autoModell.options.length] =
                new Option(autos[i][1],autos[i][1]);

          var seen = new Array();
             this.choosenModell1 = document.cars.autoModell.options;
             for (var k = choosenModell1.length; k--;) {
               //alert(choosenModell1[k]);

          if ( seen[ choosenModell1[k] ] ) {
                 // Dieser Eintrag trat schon auf
                 alert("Alt: "+choosenModell1[k]);
              document.cars.autoModell.options.length -1;
               }
               else {
                // Dieser Eintrag ist neu
                 // Hier also hinzufügen
              document.cars.autoModell.options.length=0;

          seen[ choosenModell1[k] ]= 1;

          document.cars.autoModell.options[document.cars.autoModell.options.length] =
                 new Option(autos[i][1],autos[i][1]);
              alert("Neu: "+choosenModell1[k]);
               }
               }
                       }

          }

          }
          [/code]

          Danke und Gruß
          Messmar

          1. Moin!

            Ich denke, Du solltest nicht eine Optionsliste aufbauen und dann doppelte Elemente herausnehmen, da ist nämlich der Fehler, sondern lieber die Optionsliste erst an den Stellen afbauen, wo Du ein Element das erste mal findest.

            -- Skeeve

            1. Hi,

              genau das war das erste was ich versucht zu machen, was auch logik ist.
              Aber dann wurde nichts gefunden, da die Liste vorher leer ist (konnte nichts vergleichen).

              Deswegen dachte ich mir ich fülle sie schon Mal, vergleiche die Einträge, leere ich sie wieder und am Ende mit dem nicht vorher vorhandenen Element füllen.

              Falsch gedacht??

              Danke und Gruß
              Messmar

              1. Moin!

                Ich durchschaue Dein JS nicht so ganz. Kann man das irgendwo vollständig begutachten? Gerne auch per Mail.

                -- Skeeve

  2. Hell-O!

    wie kann aber ich rausfinden, ob ein Wert aus dem zweiten Index des Arrays sich wiederholt, damit ich denn die redunanten Werte entferne.

    Am Besten, indem du die Datenstruktur änderst, eventuell bietet sich JSON an. Mal ganz einfach runtergetippt:

    var Autos = { "Renault" : [ { "Typ"      : "Clio",  
                                  "Variante" : ["1.0", "1.9"] },  
                                { "Typ"      : "Espace",  
                                  "Variante" : ["2.0", "2.2"] },  
                              ],  
                  "Opel"    : [ { "Typ"      : "Corsa",  
                                  "Variante" : ["1.0", "1.2"] },  
                                { "Typ"      : "Astra",  
                                  "Variante" : ["1.4", "1.6"] }  
                              ]  
                }
    

    Das ist natürlich nur ein Beispiel und beliebig umstrukturierbar. Auf das Objekt kannst du dann ganz einfach zugreifen:

    for(Hersteller in Autos)  
      for(i=0;i<Autos[Hersteller].length;i++)  
        document.write("<p>"+Hersteller+" "+Autos[Hersteller][i].Typ+"</p>");
    

    Die Datenstruktur müsstest du wie gesagt noch an deine Vorgaben anpassen.

    Siechfred

    --
    Ich bin strenggenommen auch nur interessierter Laie. (molily)
    Siechfreds Tagebuch || Falle Aufteilungsbescheid || RT 221 Erfurt-Altstadt i.V.
    1. Moin!

      @Mssmar: Ich habe es Dir jetzt gemailt. Dabei habe ich Siechfrieds guten Vorschlag aufgegriffen.

      Am Besten, indem du die Datenstruktur änderst,

      @Siechfried: Danke für den Hinweis auf die Initialisierung solcher Datenstrukturen. Bis dato wußte ich nicht, daß das geht!

      -- Skeeve

      1. Hallo Skeeve,
        [...]

        @Mssmar: Ich habe es Dir jetzt gemailt. Dabei habe ich Siechfrieds guten Vorschlag aufgegriffen.

        [...]

        Vielen Dank schon Mal.
        und Danke auch an Siechfred für den Tip.

        Da es von allgemeinen Interesse, dass hier auch Lösungsvroschläge gepostet werden, poste ich auch deinen Lösungsvorschlag, den ich per eMai erhalten habe, damit auch jeder User was davon hat:

        [code lang=javascript]
         var autos= {
         'Alfa Romeo' : {
          'Sportwagon' : [
           '1,6 T.Spark',
           '1,8 T.Spark',
           '1,9 JTD',
           '1,9 JTD 16V M-JET',
           '2,0 JTS',
           '2,4 JTD 20V M-JET',
           '2,5 V6 24V',
           '3,2 V6 24V GTA'
          ]
         },
         'Aston Martin' : {
          'V8 Vantage' : [
           '4,3 V8'
          ],
          'DB7' : [
           'GT',
           'GT A',
           'Vantage Coupé',
           'Vantage Volante'
          ],
          'Vanquish' : [
           'V12',
           'V12 S'
          ],
          'DB9' : [
           'Coupé',
           'Volante'
          ]
         }

        }

        function init( selection ) {
         var i= selection.options.length;
         for ( var marke in autos ) {
          selection.options[i++]= new Option( marke );
         }
        }

        function showModell( selection, variante, marke ) {
         var i= selection.options.length= variante.options.length= 1;
         for ( var modell in autos[ marke ] ) {
          selection.options[i++]= new Option( modell );
         }
        }

        function showVariante( selection, marke, modell ) {
         var i= selection.options.length= 1;
         for ( var j=0 ; j < autos[ marke ][ modell ].length ; ++j ) {
          selection.options[i++]= new Option( autos[ marke ][ modell ][ j ] );
         }
        }
        [code]

        Allerdings funkt unter FFOX, aber unter IE kommt es zu:
        "Bezeichner,Zeichenfolge oder Zahl erwartet"

        Gruß
        Messmar

        1. Hallo Skeeve,

          zu der folgenden Fehlermeldung, habe ich was gefunden und es funkt jetzt:

          die drei Funktionen haben in den Aufruf kein Value-Argument bzw. Parameter für Values. Sie müssen folgendemaßen sein:

            
            function init( selection ) {  
           var i= selection.options.length;  
           for ( var marke in autos ) {  
            selection.options[i++]= new Option( marke, marke );  
           }  
          }  
            
          function showModell( selection, variante, marke ) {  
           var i= selection.options.length= variante.options.length= 1;  
           for ( var modell in autos[ marke ] ) {  
            selection.options[i++]= new Option( modell, modell );  
           }  
          }  
            
          function showVariante( selection, marke, modell ) {  
           var i= selection.options.length= 1;  
           for ( var j=0 ; j < autos[ marke ][ modell ].length ; ++j ) {  
            selection.options[i++]= new Option( autos[ marke ][ modell ][ j ], autos[ marke ][ modell ][ j ] );  
           }  
          }  
          
          

          Aber dazu, muss man den letzten Komma am Ende des Arrays entfernen.
          und Damit funkt unter IE auch.

          Danke und Gruß
          Messmar

          1. Hallo,

            zu der folgenden Fehlermeldung, habe ich was gefunden und es funkt jetzt:

            die drei Funktionen haben in den Aufruf kein Value-Argument bzw. Parameter für Values. Sie müssen folgendemaßen sein:

            Die zwei Zeilen hier direkt oben sind falsch ;-( Sorry.

            Ich meinte das zweite Argument bei dem new Option() muss ein weiteres bzw. zweites Argument enthalten und zwar das für value.

            also:

              
            function init( selection ) {  
            ...  
                selection.options[i++]= new Option( marke, marke );  
            ...  
            }  
              
            function showModell( selection, variante, marke ) {  
            ...  
             selection.options[i++]= new Option( modell, modell );  
            ...  
            }  
              
            function showVariante( selection, marke, modell ) {  
            ...  
             selection.options[i++]= new Option( autos[ marke ][ modell ][ j ], autos[ marke ][ modell ][ j ] );  
            ...  
            }  
            
            

            Danke und Gruß
            Messmar

            1. Moin!

              Ich meinte das zweite Argument bei dem new Option() muss ein weiteres bzw. zweites Argument enthalten und zwar das für value.

              Laut SelfHTML ist das optional. Hat sich da M$ mal wieder nicht an Standards gehalten?

              -- Skeeve

              1. Ich meinte das zweite Argument bei dem new Option() muss ein weiteres bzw. zweites Argument enthalten und zwar das für value.
                Laut SelfHTML ist das optional. Hat sich da M$ mal wieder nicht an Standards gehalten?

                Nein, nur wenn du die options Abfragst ist .value dann leer, was ja auch stimmt, FF nimmt dann stattdessen .text

                Struppi.

                --
                Javascript ist toll (Perl auch!)
                1. Moin!

                  Nein, nur wenn du die options Abfragst ist .value dann leer, was ja auch stimmt, FF nimmt dann stattdessen .text

                  Danke für die Aufklärung!

                  -- Skeeve