Peter Später: Funktion greift nicht auf Variable zu...

Hallo… …eine Unklarheit gibt's noch, dann gebe ich garantiert Ruhe für heute 😀

…und zwar würde ich gerne die Werte zweier Variablen tauschen:

var Wert1 = 12;
var Wert2 = 11;

var Tauschobjekt1 = ["selfhtml-forum"];
var Tauschobjekt2 = ["rulez"];

function Tausch(o1, o2) {
	if (Wert1 > Wert2) {
		var Platzhalter = [...o2];
		o2 = o1;
		o1 = Platzhalter;
	}
}

Tausch(Tauschobjekt1, Tauschobjekt2);

console.log("Tauschobjekt1: ", Tauschobjekt1); // sollte nun ["rulez"] sein, ist nach wie vor ["selfhtml-forum"]
console.log("Tauschobjekt2: ", Tauschobjekt2); // sollte nun ["selfhtml-forum"] sein, ist nach wie vor ["rulez"]

Vielleicht bin ich auch einfach schon lange vor dem Schirm gesessen und sehe das Offensichtliche nicht mehr - aber irgendwelche Ideen dazu?

Danke, P.




[EDIT]
Bezeichnungen im Code zur besseren Verständlichkeit abgewandelt
[/EDIT]
  1. P.S.: ok, ist natürlich so, dass ich die Werte aus der Funktion auch zurückgeben muss, daher in die Richtung:

    // in Funktion
    return[o1, o2];
    
    
    var Array_vertauscht = Tausch(Tauschobjekt1, Tauschobjekt2);
    [Tauschobjekt1, Tauschobjekt2] = Array_vertauscht;
    

    ...aber ist das tatsächlich der beste gangbare Weg? Erscheint mir doch irgendwie umständlich und nicht zuletzt auch ziemlich fehleranfällig...

    1. Tach!

      P.S.: ok, ist natürlich so, dass ich die Werte aus der Funktion auch zurückgeben muss, daher in die Richtung:

      Der Grund ist, dass die Argumente lediglich als Kopie reingereicht werden. Bei Objekten sind es zwar Referenzen, aber du weist die Referenzen lediglich internen Variablen zu. Somit passiert außerhalb der Funktion nichts.

      var Array_vertauscht = Tausch(Tauschobjekt1, Tauschobjekt2);
      [Tauschobjekt1, Tauschobjekt2] = Array_vertauscht;
      

      ...aber ist das tatsächlich der beste gangbare Weg?

      Es geht ganz ohne Funktion, und die Teile dazu hast du bereits eben verwendet: Array Construction und Destructuring.

      [b, a] = [a, b]
      

      Das ist zumindest der Tauschvorgang. In deiner Funktion war noch zu sehen, dass der Tauschvorgang nur in Abhängigkeit von zwei globalen Werten stattfinden soll. Das ist eine sehr ungünstige Vorgehensweise, denn man sieht es der Funktion nicht an, dass diese beiden globalen Werte vorausgesetzt werden. Übergib lieber diese beiden Werte als zusätzliche Argumente - also falls du nun überhaupt noch eine Funktion erstellst.

      Wenn der Vergleich wichtig ist, kann man den auch in einem Ausdruck mit ternärem Operator unterbringen.

      [a, b] = x > y ? [b, a] : [a, b];
      

      Etwas unschön daran ist, dass im Kleiner-als-Fall effektiv [a, b] = [a, b] ausgeführt wird, aber das passiert ja auch für Argumente und Rückgabewerte, wenn du das in eine Funktion packst.

      if (x > y)
        [a, b] = [b, a];
      

      Das wäre ein Ausweg, aber je nachdem, was du mit den ausgetauschten Werte vorhast, ergibt sich vielleicht eine andere Bewertung der beiden Vorgehensweisen.

      Außerdem verwendest du in deiner Funktion diese Zeile

      var Platzhalter = [...o2];
      

      Die erstellt effektiv eine Kope des Arrays in o2, also wie o.slice(). Doch du weist das Funktionsergebnis wieder denselben Variablen zu (nur ausgetauscht), so dass diese Kope keinen Sinn ergibt, weil das gleich aussehende Original verschwindet und nicht mehr für andere Verarbeitungen verwendet werden kann. Da kann man gleich beim Original bleiben. Aber das hat sich auch mit erledigt, wenn du denn oben genannten Tauschvorschlag nimmst.

      dedlfix.

      1. @@dedlfix

        [a, b] = x > y ? [b, a] : [a, b];
        

        Du meinst [a, b] = a > b ? [b, a] : [a, b];?

        Und wenn das öfter vorkommt, schreibst du

        [a, b] = a > b ? [b, a] : [a, b];
        [c, d] = c > d ? [d, c] : [c, d];
        [e, f] = e > f ? [f, e] : [e, f];
        
        
        

        anstatt lesbaren Code

        [a, b] = [a, b].sort(compareNumerically);
        [c, d] = [c, d].sort(compareNumerically);
        [e, f] = [e, f].sort(compareNumerically);
        
        

        und einmaliger Definition der Vergleichsfunktion?

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Tach!

          [a, b] = x > y ? [b, a] : [a, b];
          

          Du meinst [a, b] = a > b ? [b, a] : [a, b];?

          Nein, das meine ich nicht, das entspricht nicht dem Code im OP.

          Und wenn das öfter vorkommt, schreibst du

          [a, b] = a > b ? [b, a] : [a, b];
          [c, d] = c > d ? [d, c] : [c, d];
          [e, f] = e > f ? [f, e] : [e, f];
          
          
          

          anstatt lesbaren Code

          [a, b] = [a, b].sort(compareNumerically);
          [c, d] = [c, d].sort(compareNumerically);
          [e, f] = [e, f].sort(compareNumerically);
          
          

          und einmaliger Definition der Vergleichsfunktion?

          Das entspricht nicht der Vorgabe im OP. Er vergleicht dort nicht die beiden auszutauschenden Werte sondern zwei davon unabhängige.

          dedlfix.

        2. @@Gunnar Bittersmann

          [a, b] = x > y ? [b, a] : [a, b];
          

          Du meinst [a, b] = a > b ? [b, a] : [a, b];?

          Gerade gesehen: Nein, meinst du nicht. a und b sollen nach anderen Kriterien x und y sortiert werden.

          Immer noch etwas für Array.sort(); nur sieht die Vergleichsfunktion anders aus.

          LLAP 🖖

          --
          „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
          1. Tach!

            Immer noch etwas für Array.sort(); nur sieht die Vergleichsfunktion anders aus.

            Und aus einem simplen Einzeiler wird ein komplexer.

            Man kann auch HTML größtenteils mit div schreiben, nur geht dabei die Semantik verloren (abgesehen von Funktionalität). Und man kann auch beim Programmieren die Dinge mit anderen Algorithmen umsetzen, als mit denen, die der Semantik entsprechen, von dem was man eigentlich vorhatte. Ich bin kein Fan von Code, bei dem man erst umdenken muss, um das eigentliche Ziel zu erkennen.

            dedlfix.

            1. @@dedlfix

              Ich bin kein Fan von Code, bei dem man erst umdenken muss, um das eigentliche Ziel zu erkennen.

              Eben.

              [a, b] = [a, b].sort(compare); ist sprechender Code;

              [a, b] = x > y ? [b, a] : [a, b]; ist es nicht.

              LLAP 🖖

              --
              „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
              1. Tach!

                Ich bin kein Fan von Code, bei dem man erst umdenken muss, um das eigentliche Ziel zu erkennen.

                Eben.

                [a, b] = [a, b].sort(compare); ist sprechender Code;

                [a, b] = x > y ? [b, a] : [a, b]; ist es nicht.

                Wenn die Vorgabe "tauschen" lautet, empfinde ich "sortieren" nicht als sprechend. Es kann sein, dass eine andere Vorgehensweise zum eigentlichen Ziel besser passt, aber ich mag ungern Lösungen vorstellen, von denen ich nicht weiß, ob sie passend sind oder nicht.

                Außerdem kann ich mir nicht vorstellen, dass es insgesamt effizienter ist, im Hintergrund einen Sortieralgorithmus mit Callback-Vergleichsfunktion ausführen zu lassen, statt ein paar Variablenzuweisungen mit einem Vergleich.

                dedlfix.

                1. @@dedlfix

                  Wenn die Vorgabe "tauschen" lautet, empfinde ich "sortieren" nicht als sprechend.

                  Lautet sie aber nicht. Die Vorgabe lautet: „Wenn Kriterium, dann tauschen, sonst nicht“ – kurz: „sortieren nach Kriterium“.

                  ich mag ungern Lösungen vorstellen, von denen ich nicht weiß, ob sie passend sind oder nicht.

                  Ja, ob die von mir gezeigte Datenstruktur hier passt, kann man ohne Weiteres nicht wissen.

                  Außerdem kann ich mir nicht vorstellen, dass es insgesamt effizienter ist, im Hintergrund einen Sortieralgorithmus mit Callback-Vergleichsfunktion ausführen zu lassen, statt ein paar Variablenzuweisungen mit einem Vergleich.

                  „Und es geht wohlgemerkt auch nicht darum, durch Mikrooptimierung die Lesbarkeit des Codes zu verschlechtern. Das sollte man nicht tun.“ —yours truly

                  LLAP 🖖

                  --
                  „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  2. @@Peter Später

    var Wert1 = 12;
    var Wert2 = 11;
    

    Wenn Variablenbezeichner auf …1, …2, …3 enden, ist das ein Zeichen, dass du ein Array willst. Und dieses willst du sortieren:

    var Werte = [12, 11];
    
    Werte = Werte.sort(compareNumerically);
    
    console.log(Werte); // [11, 12]
    
    function compareNumerically(a, b)
    {
    	return a - b;
    }
    
    var Tauschobjekt1 = ["selfhtml-forum"];
    var Tauschobjekt2 = ["rulez"];
    

    Warum Arrays mit jeweils einem Element?

    var Tauschobjekte = ["selfhtml-forum", "rulez"];
    
    Tauschobjekte = Tauschobjekte.sort();
    
    console.log(Tauschobjekte); // ["rulez", "selfhtml-forum"]
    

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. @@Gunnar Bittersmann

      Wenn Variablenbezeichner auf …1, …2, …3 enden, ist das ein Zeichen, dass du ein Array willst. Und dieses willst du sortieren:

      Ja, aber nicht so wie gezeigt. Du willst die Tauschobjekte nach den Werten sortieren.

      Gehören die Daten zusammen? Wenn ja, sollte sich das im Code widerspiegeln:

      var Daten = [
      	[12, "selfhtml-forum"],
      	[11, "rulez"]
      ]
      

      oder

      var Daten = [
      	{
      		Wert: 12,
      		Tauschobjekt: "selfhtml-forum" 
      	},
      	{
      		Wert: 11,
      		Tauschobjekt: "rulez" 
      	}
      ]
      

      Die Vergleichsfunktionen wären dann

      function compare(a, b)
      {
      	return a[0] - b[0];
      }
      

      bzw.

      function compare(a, b)
      {
      	return a.Wert - b.Wert;
      }
      

      Daten sortieren:

      Daten = Daten.sort(compare);
      

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  3. Hallo,

    danke euch für den Diskurs. Prinzipiell eignet sich hier für mich die Lösung von dedlfix besser, da es sich im vorliegenden Beispiel im Endcode nicht ausschließlich um numerische Vergleichswerte handelt.

    ...was aber so von mir im Pseudocode nicht angegeben wurde. = Mea Culpa.

    Gunnars Lösungsansatz wird meiner bescheidenen Einschätzung nach durchaus für weitere Anwendungsbereiche des Programms Sinn machen, weswegen ich mir seinen Lösungsansatz mit compare und sort schon mal vorsorglich als Kommentar im Quellcode verlinkt hab.

    Danke an beide! LG, Peter

    1. @@Peter Später

      da es sich im vorliegenden Beispiel im Endcode nicht ausschließlich um numerische Vergleichswerte handelt.

      Man kann in der Vergleichsfunktion auch Strings vergleichen. Im einfachsten Fall mit

      function compare(a, b)
      {
      	return a > b;
      }
      

      Was wohl auch passiert, wenn man keine eigene Vergleichsfunktion angibt. „Die Standardsortierreihenfolge folgt den Unicode Codepoints.“ [MDN]

      Das ist aber oft nicht das, was man will. Da will man eher String.localeCompare() oder Intl.Collator.compare() nutzen.

      Siehe auch: Unicode Collation Algorithm

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann