Onkel Schnitzel: Schlüsselposition eines Array in Variable speichern

Hallihallo,

Ich schreibe in meinem Script an verschiedenen Stellen einen Wert in ein Array:

SpielerdatenArray[id][1] = 90

Das wollte ich nun vereinfachen, indem ich die "Array-Position" vorher in einer Variable ablege:

var spielzeit = SpielerdatenArray[id][1];
spielzeit = 90;

Ist natürlich ganz große Programmierkunst. So wird ja einfach bloß der Wert in die Variable gespeichert und nicht ins Array. Ist das was ich machen will überhaupt möglich und wenn ja, wie heißt das Stichwort dazu? Ich hatte vor einiger Zeit mal einen Ausflug in objektorientierte Programmierung in PHP gewagt und da war so etwas möglich, wenn ich mich recht erinnere.

Beste Grüße

Onkel Schnitzel

  1. Hallo,

    SpielerdatenArray[id][1] = 90

    Das wollte ich nun vereinfachen, indem ich die "Array-Position" vorher in einer Variable ablege:

    var spielzeit = SpielerdatenArray[id][1];
    spielzeit = 90;

    das ist Humbug, denn damit initialisierst du spielzeit zunächst mit dem Wert aus SpielerdatenArray[id][1], überschreibst diesen Wert dann aber sofort mit dem Wert 90. Ist das sinnvoll? Nein, IMO nicht. Was willst du also *wirklich* erreichen?

    So wird ja einfach bloß der Wert in die Variable gespeichert und nicht ins Array.

    Ein Array ist genauso eine Variable.

    Ist das was ich machen will überhaupt möglich und wenn ja, wie heißt das Stichwort dazu?

    Keine Ahnung. Anhand deiner Beschreibung habe ich keine Ahnung, *was* du wirklich erreichen willst.

    So long,
     Martin

    --
    Ich habe gerade erfahren, dass Tante Frieda gestorben ist. Der Tod hat sie im Schlaf ereilt. - Schrecklich. Dann weiß sie es also noch gar nicht?
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Meine Herren!

      Keine Ahnung. Anhand deiner Beschreibung habe ich keine Ahnung, *was* du wirklich erreichen willst.

      In PHP ausgedrückt, möchte der OP sowas erreichen:

      $spielzeit = &$SpielerdatenArray[$id][1];  
      $spielzeit = 90;
      

      Er möchte sozusagen einen Shortcut auf das Array-Element haben.

      In JavaScript arbeitet man gewöhnlich ständig auf Referenzen. Ausnahme sind primitive Datentypen und numerische Typen zählen nun mal zu diesen. Das Vorhaben ist deshalb nur umzusetzen, indem du eine Wrappe-Klasse, um die Elemente legst.

      Was du aber problemlos machen kannst, ist eine Referenz auf die Zeile zu erstellen, also:

      spielzeiten = SpielerdatenArray[id];  
      spielzeiten[1] = 90;
      
      1. Meine Herren!

        In JavaScript arbeitet man gewöhnlich ständig auf Referenzen. Ausnahme sind primitive Datentypen und numerische Typen zählen nun mal zu diesen. Das Vorhaben ist deshalb nur umzusetzen, indem du eine Wrappe-Klasse, um die Elemente legst.

        Oh Gott, das ist überhaupt nicht das, was ich ausdrücken wollte. Die Quint-Essenz ist zwar richtig, die Begründung aber so formuliert absoluter Humbug. Ich sammel mich mal und probier 's dann nochmal richtig.

        Der Teil stimmt weiterhin:

        Was du aber problemlos machen kannst, ist eine Referenz auf die Zeile zu erstellen, also:

        spielzeiten = SpielerdatenArray[id];

        spielzeiten[1] = 90;

        
        -- 
        Hey Girl,  
        i wish you were asynchronous, so you'd give me a callback.
        
      2. In PHP ausgedrückt, möchte der OP sowas erreichen:

        $spielzeit = &$SpielerdatenArray[$id][1];

        $spielzeit = 90;

          
        Aaaah, ja stimmt, sooo war das in PHP. Ein Zeiger...  
          
        
        > Das Vorhaben ist deshalb nur umzusetzen, indem du eine Wrappe-Klasse, um die Elemente legst.  
          
        Das hört sich kompliziert an.  
          
        
        > Was du aber problemlos machen kannst, ist eine Referenz auf die Zeile zu erstellen, also:  
        >   
        > ~~~javascript
        
        spielzeiten = SpielerdatenArray[id];  
        
        > spielzeiten[1] = 90;
        
        

        Das machts natürlich nicht wesentlich übersichtlicher.

        Trotzdem besten Dank!

        1. Meine Herren!

          Das Vorhaben ist deshalb nur umzusetzen, indem du eine Wrappe-Klasse, um die Elemente legst.

          Das hört sich kompliziert an.

          Ist es nicht, der Mehrwert ist es aber auch nicht wert (Badum-Tsss).

          Im Moment hast du vielleicht so was ähnliches:

          var Spielerdaten = [];  
          Spielerdaten.push([10,20,30]);
          

          Wenn du nun statt Primitiven Objekte in die Elemente steckst, kannst du sie referenzieren.

          var Spielerdaten = [];  
          Spielerdaten.push([{x:10},{x:20},{x;30}]);
          

          Mit der Referenz könntest du dann arbeiten:

          var spielzeit = Spielerdaten[0][0];  
          var test = spielzeit.x; // lesen  
          spielzeit.x = 90; // schreiben
          

          Das dürfte Ernüchterung bringen.

          Die Essenz deiner Frage zielt, wenn ich dich richtig verstehe, auf eine bessere Lesbarkeit des Codes ab.

          Hier noch ein paar Vorschläge:

          Gehen wir von folgendem Snippet aus, das wir kürzen möchten:

          var test = [0,1,2];  
          test[0] = test[0] * 10;  
          test[1] = test[1] * 10;  
          test[2] = test[2] * 10;
          

          Variante 1:

          var test = [0,1,2];  
          test = [  
             test[0] * 10;  
             test[1] * 10;  
             test[2] * 10;  
          ];
          

          Oder Variante 2:

          var test = [0,1,2];  
          test.forEach( function( val, i, src ){ src[i] = val * 10 } );
          

          Oder Variante 3:

          var test = [0,1,2];  
          test = test.map( function( x ){ return x * 10; } );
          

          Wie weit die Beispiele auf deinen konkreten Anwendungsfall übertragbar sind, kann ich dir natürlich nicht verraten. Aber du darfst gern noch was mehr Code zeigen.

          1. Mit der Referenz könntest du dann arbeiten:

            var spielzeit = Spielerdaten[0][0];

            var test = spielzeit.x; // lesen
            spielzeit.x = 90; // schreiben

            
            >   
            > Das dürfte Ernüchterung bringen.  
              
            Nö, tuts nicht. Das sieht irgendwie schon sauberer ist und kommt dann halt dem näher, was man z.B. von jQuery her kennt.  
              
              
            
            > Oder Variante 2:  
            > ~~~javascript
            
            var test = [0,1,2];  
            
            > test.forEach( function( val, i, src ){ src[i] = val * 10 } );
            
            

            Oder Variante 3:

            var test = [0,1,2];

            test = test.map( function( x ){ return x * 10; } );

            
            >   
            > Wie weit die Beispiele auf deinen konkreten Anwendungsfall übertragbar sind, kann ich dir natürlich nicht verraten. Aber du darfst gern noch was mehr Code zeigen.  
              
            Ich glaube, damit wäre mein Code schon optimierbar, das wäre sicherlich viel schneller. Manchmal geht es halt schneller redundanten Spaghetticode zu schreiben, also zumindest dann, wenn man sich erst reindenken muss und nicht der Hellste is :-)  
              
            Ich setze meine betreffende Funktion einfach mal mit rein, auch wenn das sicherlich nicht das Gelbe vom Ei ist. Sie tut aber erstmal was sie soll, sie berechnet die Einsatzzeit eines Spielers in einem Spiel anhand verschiedener Werte aus einem mehrdimensionalen Array und schreibt diese Zeit dann ebenfalls in das Array.  
              
            Na ich bin ja mal gespannt... :-)  
              
            ~~~javascript
              
            function sumSpielzeit(id) {                     // id übergibt die ID des Spielers  
            	var zeit = 90;  
            	var einsatz = SpielerdatenArray[id][0]; // Einsatz 0/1  
            	var eingew = SpielerdatenArray[id][2]; 	// Einwechslung 0/Minute  
            	var ausgew = SpielerdatenArray[id][3]; 	// Auswechselung 0/Minute  
            	var gelb_rot = SpielerdatenArray[id][6];  // Gelb-Rot 0/Minute  
            	var rot = SpielerdatenArray[id][7];     // Rot 0/Minute  
            		  
            	// wenn kein Einsatz, alle Werte des Spieler-Arrays auf 0  
            	if (einsatz === 0) {  
            		for (n in SpielerdatenArray[id]) {  
            			SpielerdatenArray[id][n] = 0;  
            		}  
            	}  
            	// wenn Einsatz=1  
            	else {  
            		// wenn Spieler eingewechselt  
            		if(eingew !== 0) {  
            			// wenn Spieler ausgewechselt  
            			if(ausgew !==0) {  
            				SpielerdatenArray[id][1] = (ausgew)-(eingew);				  
            			}  
            			// wenn raus durch gelb_rot  
            			else if(gelb_rot !==0) {  
            				SpielerdatenArray[id][1] = (gelb_rot)-(eingew);							  
            			}  
            			// wenn raus durch rot  
            			else if(rot !==0) {  
            				SpielerdatenArray[id][1] = (rot)-(eingew);							  
            			}  
            			// wenn nur eingewechselt  
            			else {  
            				SpielerdatenArray[id][1] = zeit-(eingew-1);					  
            			}  
            		}  
            		  
            		// wenn Spieler nicht eingewechselt  
            		else {  
            			// wenn Spieler ausgewechselt...  
            			if(ausgew !==0) {  
            				SpielerdatenArray[id][1] = ausgew-1;  
            			}  
            			else if(gelb_rot !==0) {  
            				SpielerdatenArray[id][1] = gelb_rot-1;					  
            			}  
            			else if(rot !==0) {  
            				SpielerdatenArray[id][1] = rot-1;					  
            			}  
            			// wenn weder ein- noch ausgewechselt  
            			else {  
            				SpielerdatenArray[id][1] = zeit;  
            			}				  
            		}  
              
            	} // else einsatz  
            	  
            	document.getElementById('zeit['+id+']').innerHTML = SpielerdatenArray[id][1];  
            	  
            } // function  
            
            
    2. das ist Humbug...

      Ja, schon klar. In meinem Script stand das nicht direkt untereinander, da sahs nicht ganz so blöd aus.

      Keine Ahnung. Anhand deiner Beschreibung habe ich keine Ahnung, *was* du wirklich erreichen willst.

      Naja, mit var spielzeit = SpielerdatenArray[id][1] soll er eigentlich nicht den Wert des Arrays speichern, sondern quasi die Zeichenkette 'SpielerdatenArray[id][1]'.

      Mit spielzeit = 90, möchte ich dann sagen, speichere den Wert 90 in das Array. Ich möchte also den Zugriff auf diesen bestimmten Key des Arrays vereinfachen.

      Das ist jetzt nicht überlebenswichtig für mich, ich kann auch zehnmal SpielerdatenArray[id][1] schreiben, ich wollte es bloß etwas leichter lesbar machen.

      Gruß

      Onkel Schnitzel

  2. Hallo,

    Ich schreibe in meinem Script an verschiedenen Stellen einen Wert in ein Array:

    SpielerdatenArray[id][1] = 90

    var spielzeit = SpielerdatenArray[id][1];
    spielzeit = 90;

    Das sieht von außen stark danach aus, als könnte hier eine Objektorientierung helfen.

    foo[bar][5].qux.murks.lulz[123] ist natürlich nichts, was man ständig wiederholen will. Aber es ist auch ein Zeichen, dass die Aufgaben nicht sauber getrennt sind und die Daten unstrukturiert gespeichert und gekapselt sind. Dort, wo du die fraglichen Daten lesen und setzen willst, solltest du nur objekt.eigenschaft bzw. objekt.eigenschaft = schreiben müssen. Und eigentlich auch nichts anderes schreiben können.

    Hier hast du vermutlich eine Anzahl von Spielen, Spielern und Spielereinsätzen (bspw. hat Nadine Angerer beim Viertelfinalspiel der WM 2011 vermutlich 90 Minuten gespielt). Dann würde ich das auch so in Objekten umsetzen, die ggf. mit Has-many- und Belongs-to-Beziehungen verknüpft sind. Sodass du letztlich nur schreiben musst:

      
    var angerer = new Spielerin({ name: 'Nadine Angerer' });  
    var einsatz = new Spieleinsatz(angerer, { spielzeit: 90 });  
    // …  
    einsatz.spielzeit = 90;  
    alert(einsatz.spielzeit);  
    
    

    Dass Spieleinsatz nun in Spielerin referenziert wird, das Spieleinsatz in der einer Klasse Spiel referenziert wird, dass Spielerin in Mannschaft referenziert wird… das ist alles unbenommen.

    Dort, wo du nun die Spielzeit lesen und setzen wilst, brauchst du jetzt auch nicht mehr alle Daten, sondern nur das das konkrete Objekt. Dadurch reduzierst du die Abhängigkeiten und die Komplexität des Codes.

    Ich habe übrigens mal einen Einsteigervortrag zu Objektorientierung in JavaScript gehalten, falls es dich interessiert. Ferner empfehle ich meinen Artikel Organisation von JavaScripten sowie die überarbeitete und ergänzte Version.

    Mathias

    1. Hallo Mathias,

      Das sieht von außen stark danach aus, als könnte hier eine Objektorientierung helfen.

      foo[bar][5].qux.murks.lulz[123] ist natürlich nichts, was man ständig wiederholen will. Aber es ist auch ein Zeichen, dass die Aufgaben nicht sauber getrennt sind und die Daten unstrukturiert gespeichert und gekapselt sind.

      Ja, das ist wohl so, fürchte ich. Ich schreibe schrecklichen Spaghetticode, ich bin wahrscheinlich zu sehr PHP-geschädigt :-) Das hier ist allerdings auch ne Sache, die ich wahrscheinlich nicht wieder anfassen muss, wenn sie erstmal fertig ist.

      Mir sind die Vorteile von OOP ansatzweise ja bekannt, hab in PHP ja auch schon testweise damit gearbeitet. Schneller gehts dann aber halt - zumindest für den Anfang - prozedural. Ich krieg halt auch jetzt nich mehr die Kurve, zumindest bei diesem Projekt.

      Hier hast du vermutlich eine Anzahl von Spielen, Spielern und Spielereinsätzen (bspw. hat Nadine Angerer beim Viertelfinalspiel der WM 2011 vermutlich 90 Minuten gespielt). Dann würde ich das auch so in Objekten umsetzen, die ggf. mit Has-many- und Belongs-to-Beziehungen verknüpft sind. Sodass du letztlich nur schreiben musst:

      var angerer = new Spielerin({ name: 'Nadine Angerer' });
      var einsatz = new Spieleinsatz(angerer, { spielzeit: 90 });
      // …
      einsatz.spielzeit = 90;
      alert(einsatz.spielzeit);

      
      >   
      > Dort, wo du nun die Spielzeit lesen und setzen wilst, brauchst du jetzt auch nicht mehr alle Daten, sondern nur das das konkrete Objekt. Dadurch reduzierst du die Abhängigkeiten und die Komplexität des Codes.  
        
      Ja, das sieht schon viel sauberer aus, wie auch bei1UnitedPower. Ich packe z.Zt. alle Daten in ein großes Array und schleppe das die ganze Zeit rum (siehe andere Antwort).  
        
      
      > Ich habe übrigens mal einen Einsteigervortrag zu [Objektorientierung in JavaScript](http://molily.github.io/pottjs/) gehalten, falls es dich interessiert. Ferner empfehle ich meinen Artikel [Organisation von JavaScripten](http://aktuell.de.selfhtml.org/artikel/javascript/organisation/) sowie die [überarbeitete und ergänzte Version](http://molily.de/weblog/javascript-organisation).  
        
      Das werd ich mir auf jeden Fall noch reinziehen. Ich kenne auch deinen Vortrag vom MMT, den hab ich mir schon zwei, dreimal angesehen, aber leider bin ich immer so vergesslich. Hat mir aber auf jeden Fall schon weitergeholfen.  
        
      Schöne Grüße  
        
      Onkel Schnitzel