Rolf B: Multidimensionales Array sortieren: Neues Array

Beitrag lesen

Hallo dedlfix,

an der Vergleichsfunktion ist einiges im Argen. Und nicht nur da.

  • die Schleife für den Aufbau von $newArr ist sehr merkwürdig gebaut.
  • unnötiges Swapping, wie schon von Dir genannt
  • unnötiges unset einer lokalen Variablen, die verdampft am Funktionsende sowieso
  • unnötig aufwändiger Vergleich im numeric Zweig
function myCompare($a, $b, $invers = false ) {
  
  $inv = $invers ? -1 : 1;
  if ( is_string( $a ) and is_string( $b ) ) {
    return strcmp( $a, $b ) * $inv;
  } elseif ( is_numeric( $a )  and is_numeric( $b ) ) {
    if ( $a == $b ) return 0;
    if ( $a <  $b ) return -$inv;
    return $inv;
    // oder: return ($a == $b) ? 0 : (($a < $b) ? -$inv : $inv);
    // oder (PHP 7): return ($a <=> $b) * $inv;
  } 
  trigger_error( 'Nicht unterstützter Vergleich von '.gettype($a).' und '.gettype($b).' in Funktion myCompare. Erlaubt sind string und numeric', E_USER_ERROR );
}

Generell würde ich aber einen Sortier-Callback nicht unnötig mit Helpern und Abstraktion belasten. Wenn's irgendwo schnell gehen muss, dann dort. Das bedeutet: Typen prüft man vor dem Sortieren und nicht im Callback, denn ein Sortieralgorithmus packt die Einträge im Array mehrfach an. Was auch lohnt, ist die Frage nach der PHP Version: Ist es 7 oder mehr? Denn dann haben wir den Spaceship-Operator, der zum Sortieren sehr nützlich ist.

function compare_Datum_UID_Prio_Prio2 ( $a, $b ) {
  $result = $a['Datum'] <=> $b['Datum'];
  if ($result != 0) return $result;

  $result = $a['UID'] <=> $b['UID'];
  if ($result != 0) return $result;

  $result = $b['Prio'] <=> $a['Prio'];    // invers!
  if ($result != 0) return $result;

  return $b['Prio2'] <=> $a['Prio2'];    // invers!
}

Diesen Code könnte man noch weiter eindampfen, aber dann wird er schwer lesbar.

Ohne Spaceship könnte man über einen Compare-Helper nachdenken, oder es doch stumpf runterprogrammieren. Funktionsaufrufe sind vor PHP 7 deutlich langsamer gewesen.

function compare_Datum_UID_Prio_Prio2 ( $a, $b ) {
  if ($a['Datum'] < $b['Datum']) return -1;
  if ($a['Datum'] > $b['Datum']) return 1;

  if ($a['UID'] < $b['UID']) return -1;
  if ($a['UID'] > $b['UID']) return 1;

  if ($a['Prio'] < $b['Prio']) return 1;   // Invers!
  if ($a['Prio'] > $b['Prio']) return -1;

  if ($a['Prio2'] < $b['Prio2']) return 1;   // Invers!
  if ($a['Prio2'] > $b['Prio2']) return -1;

  return 0;
}

Nochmal zurück zum ersten Punkt: die Schleife für den Aufbau von $newArr ist sehr merkwürdig gebaut.

  • Ein unset auf das foreach-Item funktioniert nicht (und ist mutmaßlich auch unnötig), wegen des copy-on-write Verhaltens von PHP. Man müsste schon über eine Referenz iterieren: foreach ($arr as &$item). Dann wirken sich die unset in $arr aus.
  • $newArr[ $uid ] = []; ist unnötig, wie beim Erstellen des Testdaten-Arrays $arr gezeigt wird. PHP legt bei $newArr[ $uid ][] = $item; automatisch einen Array-Eintrag an.

Rolf

--
sumpsi - posui - obstruxi
0 50

Multidimensionales Array sortieren

Rabeneik
  • php
  1. 0
    Tabellenkalk
    1. 0
      Rabeneik
      1. 1
        raketenhandbuchleser
  2. 0
    Raktenhandbuchleser
    1. 0
      Rabeneik
      1. 0
        Raktenhandbuchleser
        1. 0
          Rabeneik
  3. 1
    Rolf B
    1. 0
      Rabeneik
      1. 0
        Rolf B
        1. 0

          Multidimensionales Array sortieren: Neues Array

          Rabeneik
          1. 0
            Rolf B
          2. 0
            Raketenhandbuchleser
            1. 0

              Mist! (Korrektur)

              Raketenhandbuchleser
              1. 0
                Rabeneik
          3. 0
            Rolf B
            1. 0
              Raketenhandbuchleser
              1. 0
                Rabeneik
                1. 0
                  Raketenhandbuchleser
                  1. 0
                    Rabeneik
                    1. 0
                      Raketenhandbuchleser
            2. 0
              Rabeneik
              1. 0
                Rolf B
                1. 0
                  Rabeneik
                  1. 0
                    Raketenwissenschaftler
                    1. 0
                      Rabeneik
                      1. 0

                        Danke fürs Danke!

                        Raketenwissenschaftler
                        1. 0
                          Raketenwissenschaftler
                          • zur info
                    2. 0
                      😁😁
                      • humor
                    3. 1
                      dedlfix
                      1. 1
                        Rolf B
                        1. 0
                          Der Martin
                      2. 0

                        Vorschläge überprüfbar überprüft

                        Raketenwissenschaftler
                        1. 0

                          Messfehler entdeckt und korrigiert. Erneute Messung:

                          Raketenwissenschaftler
                          1. 0
                            Raketenwissenschaftler
                        2. 1
                          dedlfix
                          1. -1
                            Raketenwissenschaftler
                            1. 0
                              Rolf B
                              1. 0
                                Raketenwissenschaftler,
                                1. 1
                                  Rolf B
                                  1. 0
                                    Raketenphilosoph
                                    1. 1
                                      Julius
                                      1. 0

                                        Über CPUs „wandernder“ Prozess

                                        Raketenphilosoph
                                        1. 0
                                          Rolf B
                                          1. 2
                                            Raketenphilosoph
                                          2. 0

                                            (sich kloppende threads)

                                            Raketenspaßverteiler
                                            • humor
                            2. 0
                              Rabeneik
                              1. 0
                                Raketenwissenschaftler
  4. 0
    TS