Linuchs: ORDER BY für php-array

Hallo,

ich möchte ein php-array nach Tag und Uhrzeit sortieren, konnte aber nur verwirrende Lösungsvorschläge ergoogeln. Ist das so problematisch?

Das php-array:

irgendwas  tag        uhr
---------- ---------- -----
abcde      2014-10-10 08:00
hallo      2014-10-09 11:00
moin, moin 2014-10-10 07:30

Mein Versuch sortiert nicht:

array_multisort($arr_termine, 'tag', 'uhr' );

Wie geht das?

Linuchs

  1. Habe weitergesucht und auf karlvalentin.de eine Lösung gefunden:

      // interne Tabelle sortieren  
      foreach ($arr_termine as $key => $row) {  // http://www.karlvalentin.de/660/mehrdimensionale-arrays-in-php-bequem-sortieren.html  
        $tag[$key] = $row['tag'];  
        $uhr[$key] = $row['uhr'];  
      }  
      array_multisort( $tag, SORT_ASC, $uhr, SORT_ASC, $arr_termine );  
    
    

    Linuchs

  2. Tach!

    Mein Versuch sortiert nicht:
    array_multisort($arr_termine, 'tag', 'uhr' );

    array_multisort() ist meist ungeeignet, wil es nicht das eher übliche datensatzorientierte Array (Array mit Datensatz-Arrays als Elementen) haben möchte, sondern ein Spaltenarray (Array mit Tabellenspalten als Elemente) benötigt.

    Wie geht das?

    Eine der usort-Funktionen und eine benutzerdefinierte Vergleichsfunktion (kann man direkt anonym übergeben) verwenden ist die übliche und verständlichere) Vorgehensweise.

    dedlfix.

    1. Hi dedlfix,

      ja, dass hab ich mir auch überlegt. Was mich daran gehindert hat Linuchs die usort-Funktion an's Herz zu legen war, dass er Datum und Uhrzeit in 2 Spalten aufteilt und er keine Timestamps verwendet.

      Dann nämlich ist die Verständlichkeit der usort Funktion m.M. auch nicht mehr besser als die multisort - Funktion.
      Z.B.:

      usort($arr_termine, function($a, $b) {  
        $a_ts = new DateTime($a['tag'].' '.$a['uhr']);  
        $b_ts = new DateTime($b['tag'].' '.$b['uhr']);  
        
        if ($a_ts == $b_ts) { return 0; }  
        return $a_ts < $b_ts ? 1 : -1;  
      });
      

      P.S.: Code nicht getestet.

      Linuchs könnte auch u.U. eine Array-Spalte sparen und Datum und Uhrzeit zu einem timestamp zusammenfügen.

      lg
      mark

      1. Tach!

        Was mich daran gehindert hat Linuchs die usort-Funktion an's Herz zu legen war, dass er Datum und Uhrzeit in 2 Spalten aufteilt und er keine Timestamps verwendet.

        Das ist in dem speziellen anscheinend kein Problem, denn die Zeitwerte liegen in einer als String vergleichbaren Form vor. Alternativ könnte er die Werte als Unix-Timestamp vom DBMS liefern lassen, sie als Integer vergleichen und erst bei der Ausgabe formatieren. Das käme auch der Mehrsprachigkeit zugute, falls das ein Kriterium ist.

        $a_ts = new DateTime($a['tag'].' '.$a['uhr']);
          $b_ts = new DateTime($b['tag'].' '.$b['uhr']);
          if ($a_ts == $b_ts) { return 0; }
          return $a_ts < $b_ts ? 1 : -1;

        Hat DateTime eine eingebaute Magie, die es erlaubt, zwei Objekte derart miteinander zu vergleichen? Eigenen Objekten kann man ja keine Operatoren überladen.

        dedlfix.