romero: Array-Splice

hallo ich bins wieder :)

wie setzte ich splice richtig ein, so das er alle werte eines array's löscht ausser die, wo die anzahl am höchsten ist?

was vor ab:

durch's anklicken von verschiedenen werten einer auswahlliste, erzeuge ich ein array mit unterschiedlichem inhalt. diesen lasse ich mir sortieren und wie gesagt, wenn entsprechende werte gleich sind, die dazugehörige anzahl.

aber wie kann ich, wenn es mehr als ein gleicher eintrag ist, den oder die vorherigen löschen?

hier mal ein code-auszug:

			var ZusatzmatteAuswählen = function()  
			{  
				var infile_zusatz_1 = new Array();  
				var infile_zusatz_2 = [];  
				var last = "";  
				var infile_zusatz_last = "";  
				var infile_zusatz_zaehler = 1;  
  
				var Zusatz_HTZ = document.Auswahl.Zusatz.options[document.Auswahl.Zusatz.selectedIndex].text;  
				var Zusatz_Variante = document.Auswahl.ZusatzVariante.options[document.Auswahl.ZusatzVariante.selectedIndex].text;  
  
				infile_zusatz = infile_zusatz.concat( Zusatz_HTZ + "_" + Zusatz_Variante );  
  
				infile_zusatz.sort();  
  
				var x = Zusatz_HTZ + "_" + Zusatz_Variante;  
  
				document.getElementById("msgs").innerHTML = "";  
  
				for( var i = 0; i < infile_zusatz.length; i++ )  
				{  
					if( last == infile_zusatz[i] )  
					{  
						infile_zusatz_zaehler++;  
  
					} else {  
							infile_zusatz_zaehler = 1;  
						}  
  
					last = infile_zusatz[i];  
  
					msg( infile_zusatz[i] + " / " + infile_zusatz_zaehler + "<br>" );  
  
					infile_zusatz_1 = infile_zusatz_1.concat( infile_zusatz[i] + "/" + infile_zusatz_zaehler );  
				}  
  
				for( var i = 0; i < infile_zusatz_1.length; i++ )  
				{  
					if( infile_zusatz_1[i].substr( 15, 1 ) > "1" )  
					{  
						infile_zusatz_1.splice( infile_zusatz_1[i].substr( 15, 1 )-i, 1 );  
  
						msg( i + " " + infile_zusatz_1[i] + "<br>" )  
					}  
				}  
			}

und das wäre mal ein resultat dieser liste:

die einzelnen einträge sortiert:

D258_70095_008 / 1
D258_70095_008 / 2
D258_70095_008 / 3
D258_70095_008 / 4
D258_70095_008 / 5
D258_70095_008 / 6
D258_70095_008 / 7
D258_70095_016 / 1
D258_70095_016 / 2
D258_70095_016 / 3
D258_70095_036 / 1
D258_70095_036 / 2

die angeblich letzten gelöschten einträge ausser den mit der höchsten anzahl:
1 D258_70095_008/3
2 D258_70095_008/5
3 D258_70095_008/7
5 D258_70095_016/2
7 undefined  -> und warum hier undefined?sollte doch 'D258_70095_036 / 2' hin

lg romero

  1. wie setzte ich splice richtig ein, so das er alle werte eines array's löscht ausser die, wo die anzahl am höchsten ist?

    Gar nicht. Array.splice löscht bedingungslos je nachdem welche Parameter du angibst.

    aber wie kann ich, wenn es mehr als ein gleicher eintrag ist, den oder die vorherigen löschen?

    Willst du einfach doppelte Einträge entfernen?
    Das geht realtiv einfach und es sollten sich auch schnell Lösungen finden.

    Struppi.

    1. hy

      Willst du einfach doppelte Einträge entfernen?
      Das geht realtiv einfach und es sollten sich auch schnell Lösungen finden.

      Struppi.

      doppelte,dreifache,...

      so ist der inhalt des array's:

      D258_70095_008 / 1
      D258_70095_008 / 2
      D258_70095_008 / 3
      D258_70095_008 / 4
      D258_70095_008 / 5
      D258_70095_008 / 6
      D258_70095_008 / 7
      D258_70095_016 / 1
      D258_70095_016 / 2
      D258_70095_016 / 3
      D258_70095_036 / 1
      D258_70095_036 / 2

      am ende soll es so aussehen:

      D258_70095_008 / 7
      D258_70095_016 / 3
      D258_70095_036 / 2

      wobei die zahl am ende die anzahl darstellt.

      ich dachte es geht mit splice und das in eine schleife gepackt.naja hoffe einer kann einen ansatz geben.vielen dank schonmal.

      lg romero

      1. Hey Romero,

          
                                        for( var i = 0; i < infile_zusatz_1.length; i++ )  
                                        {  
                                                if( infile_zusatz_1[i].substr( 15, 1 ) > "1" )  
                                                {  
                                                        infile_zusatz_1.splice( infile_zusatz_1[i].substr( 15, 1 )-i, 1 );  
          
                                                        msg( i + " " + infile_zusatz_1[i] + "<br>" )  
                                                }  
                                        }  
        
        

        das hier ist ja die Funktion, in der Du alle "doppelten" Einträge löschen möchtest. Dazu:
        1. Möchtest Du in der if-Abfrage prüfen, ob der Teilstring größer 1 ist? Das hieße ja, dass die Elemnte 2, 3, 4, ... gelöscht werden. Du wolltest aber doch das größte behalten? Und kann die Anzahl der Elemente auch zweistellig werden? Schau Dir nochmal die Funktionhttp://de.selfhtml.org/javascript/objekte/string.htm#substr@title=substr an.

        2. Die Funktion http://de.selfhtml.org/javascript/objekte/array.htm#splice@title=splice erwartet als 1. Parameter die Indexnummer im Array. Du holst den Substring 1, 2, 3, usw. und ziehst von diesem dann die Anzahl der Schleifendurchgänge ab?

        3. Bei msg fehlt ein Semikolon am Ende.

        Gruß, Dennis

        1. das hier ist ja die Funktion, in der Du alle "doppelten" Einträge löschen möchtest. Dazu:

          1. Möchtest Du in der if-Abfrage prüfen, ob der Teilstring größer 1 ist? Das hieße ja, dass die Elemnte 2, 3, 4, ... gelöscht werden. Du wolltest aber doch das größte behalten? Und kann die Anzahl der Elemente auch zweistellig werden? Schau Dir nochmal die Funktionhttp://de.selfhtml.org/javascript/objekte/string.htm#substr@title=substr an.

          Könnten auch mehrstellige sein am ende. Aber mir geht’s ja erstmal dadrum, dass er überhaupt die „kleineren“ werte löscht. Hab die Formel umgebaut.

          				for( var i = 0; i < infile_zusatz_1.length; i++ )  
          				{  
          					if( "1" < infile_zusatz_1[i].substr( 15, 1 ) )  
          					{  
          						infile_zusatz_1.splice( i-1, 1 );  
            
          						msg( i + " " + infile_zusatz_1[i] + "<br>" );  
          					}  
          				}
          

          Da passiert genau das selbe, dass er nur bestimmte ausgibt.

          1. Die Funktion http://de.selfhtml.org/javascript/objekte/array.htm#splice@title=splice erwartet als 1. Parameter die Indexnummer im Array. Du holst den Substring 1, 2, 3, usw. und ziehst von diesem dann die Anzahl der Schleifendurchgänge ab?

          Ja so hab ich es mir gedacht, dass es so geht. Denn wenn die Anzahl z.B. 5 ist, dann ist er ja an der 4. Stelle der for-Schleife oder ( also gezählt von 0)? Und 5-4=1 sprich er hat nur noch 1 Eintrag stehen mit der richtigen Anzahl. Dacht ich jedenfalls.

          1. Bei msg fehlt ein Semikolon am Ende.

          Gruß, Dennis

          Bemerkt und behoben.

          1. Hey Romero,

            versuchs mal so. So in der Art hat's bei eigentlich immer funktioniert.

            1. Sortiere das array absteigend (oder aufsteigend)
            2. For-Schleife über das gesamte Array mit inkrementellem Zähler (dekrementellem Zähler)
            3. Wenn der Zähler sich nicht im ersten Durchlauf befindet, prüfe, ob der Substring (den du oben schon verwendest, wobei Du den optionalen zweiten Parameter weglässt) dem Substring des zuletzt durchlaufenen Elements entspricht. Wenn ja, dann das aktuelle Element löschen.

            Hab's grad nicht getestet, müsste aber in etwa so funktionieren.

            Gruß, Dennis

            1. Hey Romero,

              versuchs mal so. So in der Art hat's bei eigentlich immer funktioniert.

              1. Sortiere das array absteigend (oder aufsteigend)
              2. For-Schleife über das gesamte Array mit inkrementellem Zähler (dekrementellem Zähler)
              3. Wenn der Zähler sich nicht im ersten Durchlauf befindet, prüfe, ob der Substring (den du oben schon verwendest, wobei Du den optionalen zweiten Parameter weglässt) dem Substring des zuletzt durchlaufenen Elements entspricht. Wenn ja, dann das aktuelle Element löschen.

              Hab's grad nicht getestet, müsste aber in etwa so funktionieren.

              Ist aber umständlich für das was er will:

              Array.prototype.unique = function() {  
                  var o = {};  
                  var tmp = [];  
                  for(var i = 0 ; i < this.length; ++i) o[this[i]] = true;  
                
                  for(var i in o) tmp[tmp.length] = i;  
                  return tmp;  
              };  
                
              var T = [  
              'D258_70095_008',  
              'D258_70095_008',  
              'D258_70095_008',  
              'D258_70095_008',  
              'D258_70095_008',  
              'D258_70095_008',  
              'D258_70095_008',  
              'D258_70095_016',  
              'D258_70095_016',  
              'D258_70095_016',  
              'D258_70095_036',  
              'D258_70095_036',  
              ]  
                
              T = T.unique();  
              alert(T.sort().join('\n'));  
                
              
              

              Struppi.

              1. Ist aber umständlich für das was er will:

                Array.prototype.unique = function() {

                var o = {};
                    var tmp = [];
                    for(var i = 0 ; i < this.length; ++i) o[this[i]] = true;

                for(var i in o) tmp[tmp.length] = i;
                    return tmp;
                };

                var T = [
                'D258_70095_008',
                'D258_70095_008',
                'D258_70095_008',
                'D258_70095_008',
                'D258_70095_008',
                'D258_70095_008',
                'D258_70095_008',
                'D258_70095_016',
                'D258_70095_016',
                'D258_70095_016',
                'D258_70095_036',
                'D258_70095_036',
                ]

                T = T.unique();
                alert(T.sort().join('\n'));

                
                >   
                > Struppi.  
                  
                habs grad mal getestet.hab aber auch die anzahl in das array T mit eingefügt.ohne der anzahl klappt es.mit ihr nicht.und die sollte ja schon mit bei sein.also nur jeweils 1 eintrag mit der dazugörigen anzahl,sprich wie oft ich diesen eintrag gewählt habe.  
                  
                lg romero
                
                1. habs grad mal getestet.hab aber auch die anzahl in das array T mit eingefügt.ohne der anzahl klappt es.mit ihr nicht.und die sollte ja schon mit bei sein.also nur jeweils 1 eintrag mit der dazugörigen anzahl,sprich wie oft ich diesen eintrag gewählt habe.

                  Das kannst du ohne Problem in die Funktion unique einbauen:

                  Array.prototype.unique = function() {  
                      var o = {};  
                      var tmp = [];  
                      for(var i = 0 ; i < this.length; ++i)  
                      if(!o[this[i]])  o[this[i]] = 1;  
                      else o[this[i]]++;  
                    
                      for(var i in o) tmp[tmp.length] = i + '/' + o[i];  
                      return tmp;  
                  };  
                  
                  

                  Struppi.

                  1. diese var T=[ ... ] ist doch ein array oder?weil das sind ja die angaben welche ich auswähle oder?

                    dieses "T" oder bei mir infile_zusatz befülle ich so:

                    infile_zusatz = infile_zusatz.concat( Zusatz_HTZ + "_" + Zusatz_Variante );

                    aussehen tut's bei mir so:

                    			var ZusatzmatteAuswählen = function()  
                    			{  
                    				var Zusatz_HTZ = document.Auswahl.Zusatz.options[document.Auswahl.Zusatz.selectedIndex].text;  
                    				var Zusatz_Variante = document.Auswahl.ZusatzVariante.options[document.Auswahl.ZusatzVariante.selectedIndex].text;  
                      
                    				infile_zusatz = infile_zusatz.concat( Zusatz_HTZ + "_" + Zusatz_Variante );  
                      
                    				document.getElementById("msgs").innerHTML = "";  
                      
                    				Array.prototype.unique = function()  
                    				{  
                    					var o = {};  
                    					var tmp = [];  
                    					for(var i = 0 ; i < this.length; ++i)  
                    						if(!o[this[i]])  o[this[i]] = 1;  
                    						else o[this[i]]++;  
                      
                    					for(var i in o) tmp[tmp.length] = i + '/' + o[i] + "<br>";  
                    					return tmp;  
                    				};  
                      
                    				infile_zusatz = infile_zusatz.unique();  
                    				msg( infile_zusatz.sort().join('\n') );  
                      
                    			}
                    

                    wenn ich aber nun 3 sachen ausgewählt habe erscheint das bei mir:

                    D258_70096_204/1
                    D258_70096_204/1
                    /1
                    D258_70096_204/1
                    /1
                    /1

                    was mache ich falsch?zumal deine variante mit dem, im vornherein festgesetzten var T, ja klappt.

                    lg romero

                    1. fehler gefunden.muss ja mit 2 var's arbeiten.denn sonst wird ja meine ausgangsvariable mit dem neuen überschrieben.

                      so klappt es:

                      				infile_zusatz_tmp = infile_zusatz_tmp.concat( Zusatz_HTZ + "_" + Zusatz_Variante );  
                        
                      				document.getElementById("msgs").innerHTML = "";  
                        
                      				Array.prototype.unique = function()  
                      				{  
                      					var o = {};  
                      					var tmp = [];  
                      					for(var i = 0 ; i < this.length; ++i)  
                      						if(!o[this[i]])  o[this[i]] = 1;  
                      						else o[this[i]]++;  
                        
                      					for(var i in o) tmp[tmp.length] = i + ' / ' + o[i] + ' <input type="button" value="X"></input><br>';  
                      					return tmp;  
                      				};  
                        
                      				infile_zusatz = infile_zusatz_tmp.unique();  
                        
                      				msg( infile_zusatz.sort().join('\n') );
                      
                    2. aussehen tut's bei mir so:

                      [code lang=javascript] var ZusatzmatteAuswählen = function()
                      {
                      var Zusatz_HTZ = document.Auswahl.Zusatz.options[document.Auswahl.Zusatz.selectedIndex].text;
                      var Zusatz_Variante = document.Auswahl.ZusatzVariante.options[document.Auswahl.ZusatzVariante.selectedIndex].text;

                        		infile\_zusatz = infile\_zusatz.concat( Zusatz\_HTZ + "\_" + Zusatz\_Variante );  
                      

                      Ist inifile_zusatz überhaupt ein Array? Wenn ja, dann verwende besser die Methode .push, Array.concat verknüpft zwei Arrays.

                        		Array.prototype.unique = function()  
                      

                      Den Prototyp musst du nicht in der Funktion deklarieren, der paßt besser irgendwo ausserhalb hin.

                      wenn ich aber nun 3 sachen ausgewählt habe erscheint das bei mir:

                      Deine Logik scheint mir falsch. Du willst ja nicht bei jeder Auswahl auf's neue Array.unique aufrufen, sondern erst dann wenn alle Elemente ermittelt werden und dann wenn du mit dem Array inifile_zusatz etwas machen willst.

                      Struppi.

                      1. wenn ich aber nun 3 sachen ausgewählt habe erscheint das bei mir:

                        Deine Logik scheint mir falsch. Du willst ja nicht bei jeder Auswahl auf's neue Array.unique aufrufen, sondern erst dann wenn alle Elemente ermittelt werden und dann wenn du mit dem Array inifile_zusatz etwas machen willst.

                        Struppi.

                        naja teils-teils.bei jeder auswahl soll ja die gesamtsumme dastehen.deswegen lasse ich es schon mit aufrufen.

                        und deswegen wollte ich an dieser stelle bei for(var i in o) tmp[tmp.length] = i + ' / ' + o[i] + "<br>"; eine function einbauen,wo ich die summe wieder abziehen kann bzw den eintrag im array löschen kann.

                        1. naja teils-teils.bei jeder auswahl soll ja die gesamtsumme dastehen.deswegen lasse ich es schon mit aufrufen.

                          Ja das meinte ich mit fehlender Logik.
                          Meine Funktion dient eigentlich nur dazu, aus einem Array doppelte Einträge zu entfernen und nicht die Summen zu ermitteln. Das hattest du ja auch ursprünglich nicht so gefragt. Es wäre einfacher wenn du das fragst, was du wirklich Wissen willst, denn auch dafür gäbe es eine Lösung.

                          und deswegen wollte ich an dieser stelle bei for(var i in o) tmp[tmp.length] = i + ' / ' + o[i] + "<br>"; eine function einbauen,wo ich die summe wieder abziehen kann bzw den eintrag im array löschen kann.

                          Das wäre z.b. nicht nötig, wenn du eine Funktion hättest, die dir einfach die Anzahl der Einträge ermittelt.

                          Und was die Logik angeht: Was willst du denn letztendlich abziehen? Die ermittelte Anzahl des jeweiligen Eintrag oder willst du einen Eintrag aus dem Array entfernen?

                          Struppi.

                          1. naja teils-teils.bei jeder auswahl soll ja die gesamtsumme dastehen.deswegen lasse ich es schon mit aufrufen.

                            Ja das meinte ich mit fehlender Logik.
                            Meine Funktion dient eigentlich nur dazu, aus einem Array doppelte Einträge zu entfernen und nicht die Summen zu ermitteln. Das hattest du ja auch ursprünglich nicht so gefragt. Es wäre einfacher wenn du das fragst, was du wirklich Wissen willst, denn auch dafür gäbe es eine Lösung.

                            Stimmt hatte ich nicht. Es soll die summe einzelner einträge ermittelt werden und überflüssige löschen (also das nur jeweils 1 eintrag da ist).
                            Gesamtsumme war schon wieder,meinerseits,etwas falsch ausgedrückt.

                            und deswegen wollte ich an dieser stelle bei for(var i in o) tmp[tmp.length] = i + ' / ' + o[i] + "<br>"; eine function einbauen,wo ich die summe wieder abziehen kann bzw den eintrag im array löschen kann.

                            Das wäre z.b. nicht nötig, wenn du eine Funktion hättest, die dir einfach die Anzahl der Einträge ermittelt.

                            Und was die Logik angeht: Was willst du denn letztendlich abziehen? Die ermittelte Anzahl des jeweiligen Eintrag oder willst du einen Eintrag aus dem Array entfernen?

                            Struppi.

                            In mein array,welches ich durch die auswahllisten befülle,soll auf meinem bildschirm nur jeweils ein eintrag angezeigt werden (sofern diese gleich sind) mit deren anzahl,wie oft ich sie halt ausgewählt habe.das macht deine function auch wunderbar.stellt es jedenfalls so dar.und kann auch diese infile_zusatz für andere function verwenden.
                            Nun soll aber die möglichkeit bestehen,dass,wenn man einmal zu viel geklickt hat,dass man mittels einem button eine anzahl wieder abziehen kann,bis hin zum löschen von diesem eintrag.

                            Ich kann ja eine weiter function schreiben, wo ich dann einfach aus der infile_zusatz,welche am ende ja nur jeweils einen eintrag mit der entsprechenden anzahl ausweist,solange abziehe,bis die anzahl 0 ist bzw dieser eintrag gelöscht wird.ich dachte aber es geht schon in deiner.

                            Lg romero

                            1. hab das problem anderser gelöst.

                              sieht jetzt so aus:

                              		function init_Zusatzmatten()  
                              		{  
                              			var infile_zusatz_tmp = new Array();						//--> temp-Array für die Zusatzmatten nach dem Auswählen  
                              			var infile_zusatz_anzahl_tmp = new Array();					//--> temp-Array für die Zusatzmatten-Anzahl nach dem Auswählen  
                              			var infile_zusatz = new Array();  
                              			var zaehler = 1;  
                                
                              ...  
                                
                              			var ZusatzmatteAuswählen = function()  
                              			{  
                              				var z = 0;								//--> Zähler, wenn ungleich ist  
                                
                              				var Zusatz_HTZ = document.Auswahl.Zusatz.options[document.Auswahl.Zusatz.selectedIndex].text;  
                              				var Zusatz_Variante = document.Auswahl.ZusatzVariante.options[document.Auswahl.ZusatzVariante.selectedIndex].text;  
                                
                              				var x = Zusatz_HTZ + "_" + Zusatz_Variante;  
                                
                              				document.getElementById("msgs").innerHTML = "";  
                                
                              				if( infile_zusatz_tmp.length != 0 )  
                              				{  
                              					for( var i = 0; i < infile_zusatz_tmp.length; i++ )  
                              					{  
                              						if( x == infile_zusatz_tmp[i] )  
                              						{  
                              							infile_zusatz_anzahl_tmp[i]++;  
                                
                              						} else { z++; }  
                              					}  
                                
                              					if( z == infile_zusatz_tmp.length )  
                              					{  
                              						infile_zusatz_tmp.push( Zusatz_HTZ + "_" + Zusatz_Variante );  
                              						infile_zusatz_anzahl_tmp.push( zaehler );  
                              					}  
                                
                              				} else {  
                              						infile_zusatz_tmp.push( Zusatz_HTZ + "_" + Zusatz_Variante );  
                              						infile_zusatz_anzahl_tmp.push( zaehler );  
                              					}  
                                
                              ...  
                                
                              				for( var i = 0; i < infile_zusatz_tmp.length && infile_zusatz_anzahl_tmp.length; i++ )  
                              				{  
                              					msg( infile_zusatz_tmp[i] + " / " + infile_zusatz_anzahl_tmp[i] + ' <input type="button" value="x" id="LöscheninfileZusatz" class="STL_Meldungen_Button" onclick="weiß hier nicht weiter"></input><br>' );  
                              				} }; };
                              

                              an der stelle, wo ich 'onclick="weiß hier nicht weiter"' stehen hab, komm ich nicht weiter. da soll nun nach jeden button-drücken von infile_zusatz_anzahl_tmp[i] die zahl 1 abgezogen werden.solange bis die zahl 0 erreicht ist und dann die zeile[i] ge"splice"d wird. kann mir da einer helfen?

                              lg romero

                              1. kann mir dazu keiner helfen?hab schon selber viele wege versucht,aber keines scheint zu klappen.entweder zieht er vom letzten "i" was ab oder dann funktionert (bei mehr als einer eingabe) der letzte button nicht.also alles irgendwie nicht so zwingend.

                                deswegen hoff ich auf einen tipp wie es klappen könnte.passieren soll es,denk ich,in dier besagten for-schleife.

                                lg romero

                  2. hallo struppi,

                    gibt es da noch die möglichkeit mittels einem button die "anzahl", also o[i] wieder rückgängig zu machen,und soweit bis hin zum löschen des einzelnen array's-eintrag?

                    dachte da an sowas hier:

                    tmp[tmp.length] = i + ' / ' + o[i] + <input type="button" value="x" name="infileZusatz" id="infileZusatz" class="STL_Meldungen_Button" onclick=new Function( "der inhalt zum reduzieren und löschen");></input><br>;

                    ich denke, dass an dieser stelle der zähler rückwerts laufen soll, wenn man den button drückt.bis hin zum löschen.ginge das so?

                    lg romero

                    1. gibt es da noch die möglichkeit mittels einem button die "anzahl", also o[i] wieder rückgängig zu machen,und soweit bis hin zum löschen des einzelnen array's-eintrag?

                      Das hatte ich nur eingebaut, weil du es brauchst, brauchst du das wirklich?
                      Dann solltest du das vielleicht besser irgendwo anders abspeichern und nicht in den Auswahlmöglichkeiten.

                      ich denke, dass an dieser stelle der zähler rückwerts laufen soll, wenn man den button drückt.bis hin zum löschen.ginge das so?

                      Nein, dein Vorschlag macht keinen Sinn.

                      Struppi.

      2. Willst du einfach doppelte Einträge entfernen?
        Das geht realtiv einfach und es sollten sich auch schnell Lösungen finden.

        Struppi.

        Ich weiß nicht ob ich dich nicht schon mal gebeten, nur das zu zitieren worauf du antwortest, es wäre nett, wenn du das beherzigen würdest, es macht deine ohnehin schwer zu verstehenden Postings, etwas übersichtlicher.

        doppelte,dreifache,...

        Warum googlst du nicht kruz, anstatt wild etwas auszuprobieren?
        javascript array, doppelte entfernen liefert doch schon viele anhaltspunkte.

        Struppi.