Nick: Dateien nach Dateityp sortieren

Hallo!

Gegeben ist ein Array, das eine Reihe von Dateinamen verschiedenen Typs beinhaltet:

Array  
(  
    [0] => musik.mp3  
    [1] => bild.jpg  
    [2] => mehr_musik.mp3  
    [3] => noch_ein_bild.jpg  
    [4] => text.txt  
    [5] => textdokument.doc  
)

Nun sollen nach Dateityp sortierte Listen ausgegeben werden, die in sich wiederum alphabetisch sortiert sind:

<h1>DOC</h1>  
<ul>  
<li>textdokument.doc</li>  
</ul>  
  
<h1>JPG</h1>  
<ul>  
<li>bild.jpg</li>  
<li>noch_ein_bild.jpg</li>  
</ul>  
  
<h1>MP3</h1>  
<ul>  
<li>mehr_musik.mp3</li>  
<li>musik.mp3</li>  
</ul>  
  
<h1>TXT</h1>  
<ul>  
<li>text.txt</li>  
</ul>

Wie stellt man das am besten (möglichst performant) an?

Beste Grüße
Nick

  1. Hello,

    Gegeben ist ein Array, das eine Reihe von Dateinamen verschiedenen Typs beinhaltet:

    Schon zu spät.

    Array

    (
        [0] => musik.mp3
        [1] => bild.jpg
        [2] => mehr_musik.mp3
        [3] => noch_ein_bild.jpg
        [4] => text.txt
        [5] => textdokument.doc
    )

    
    >   
    > Nun sollen nach Dateityp sortierte Listen ausgegeben werden, die in sich wiederum alphabetisch sortiert sind:  
      
    
    > Wie stellt man das am besten (möglichst performant) an?  
      
    Um wieviel Tausend Dateien handelt es sich denn?  
      
    Was meinst Du jetzt? Das Auswählen, das Sortieren oder das Aufbereiten der Anzeige?  
      
    Wie beschaffst Du die Dateinamen?  
      
    Weißt Du vorher, welche Dateiendungen gefunden werden sollen, oder ergibt sich das erst durch die Abfrage des Filesystems?  
      
      
      
    Liebe Grüße aus dem schönen Oberharz  
      
      
    Tom vom Berg  
    ![](http://selfhtml.bitworks.de/Virencheck.gif)  
      
    
    -- 
     ☻\_  
    /▌  
    / \ Nur selber lernen macht schlau  
    <http://bergpost.annerschbarrich.de>
    
    1. Hallo Tom!

      Danke für deine Antwort.

      Um wieviel Tausend Dateien handelt es sich denn?

      Weit davon entfernt, es sind nur eine Hand voll Dateien.

      Was meinst Du jetzt? Das Auswählen, das Sortieren oder das Aufbereiten der Anzeige?

      Das Sortieren in erster Linie, aber auch die Trennung (jeweils eigene Unsorted List pro Dateityp).

      Wie beschaffst Du die Dateinamen?

      Mit scan().

      Weißt Du vorher, welche Dateiendungen gefunden werden sollen, oder ergibt sich das erst durch die Abfrage des Filesystems?

      Das ergibt sich erst.

      Beste Grüße
      Nick

      1. Hello Nick,

        Wie beschaffst Du die Dateinamen?

        Mit scan().

        Weißt Du vorher, welche Dateiendungen gefunden werden sollen, oder ergibt sich das erst durch die Abfrage des Filesystems?

        Das ergibt sich erst.

        Lass Dir bitte nicht alle Informationen einzeln aus der Nase ziehen ;-P

        Du muss also ein ganzes Verzeichnis auslesen und willst diese Liste dann in Gruppen sortieren?

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Du muss also ein ganzes Verzeichnis auslesen und willst diese Liste dann in Gruppen sortieren?

          So ist es.

          1. Hallo,

            Du muss also ein ganzes Verzeichnis auslesen und willst diese Liste dann in Gruppen sortieren?

            So ist es.

            und was stört Dich an dedlfix' perfektem Vorschlag?

            Freundliche Grüße

            Vinzenz

            1. Hallo Vinzenz!

              Danke für deine Antwort.

              und was stört Dich an dedlfix' perfektem Vorschlag?

              Eigentlich nichts. ;-)

              Beste Grüße
              Nick

    2. Lohnt es sich hier eigentlich aus Performance-Gründen opendir() mit readdir() statt scan() zu verwenden? Denn die implizite Sortierung von scan() wird hier ja nicht gebraucht.

      1. Tach!

        Lohnt es sich hier eigentlich aus Performance-Gründen opendir() mit readdir() statt scan() zu verwenden? Denn die implizite Sortierung von scan() wird hier ja nicht gebraucht.

        Die mehrfachen Funktionsaufrufe werden vermutlich mehr kosten als der eine Aufruf von scandir() (nicht nur scan()). Die Sortierung kann man auch deaktivieren (siehe Beschreibung im Handbuch). Eine Alternative kann glob() sein, das lässt . und .. weg, man muss also auch nicht darauf testen, wenn man das nicht haben möchte. Insgesamt dürften die Performance-Unterschiede jedoch nicht ins Gewicht fallen.

        dedlfix.

        1. Die mehrfachen Funktionsaufrufe werden vermutlich mehr kosten als der eine Aufruf von scandir() (nicht nur scan()).

          Ach so. (Ups, ja, scandir() natürlich.)

          Die Sortierung kann man auch deaktivieren (siehe Beschreibung im Handbuch).

          Wie denn? Ich lese aus dem Handbuch nur heraus, wie man die Sortierung auf "alphabetisch absteigend" ändern kann.

          Eine Alternative kann glob() sein, das lässt . und .. weg, man muss also auch nicht darauf testen, wenn man das nicht haben möchte.

          Vielen Dank für den Tipp! Ansonsten kann man . und .. ja auch mit array_diff() eliminieren, anstatt darauf zu testen.

          Insgesamt dürften die Performance-Unterschiede jedoch nicht ins Gewicht fallen.

          Ok, vielen Dank.

          1. Tach!

            Die Sortierung kann man auch deaktivieren (siehe Beschreibung im Handbuch).
            Wie denn? Ich lese aus dem Handbuch nur heraus, wie man die Sortierung auf "alphabetisch absteigend" ändern kann.

            Also, im englischen Original sieht man, dass der Parameter $sorting_order erweitert wurde. Der kennt jetzt auch einen konstanten Wert namens SCANDIR_SORT_NONE - allerdings erst ab der nächsten Version (5.4).

            dedlfix.

            1. Also, im englischen Original sieht man, dass der Parameter $sorting_order erweitert wurde. Der kennt jetzt auch einen konstanten Wert namens SCANDIR_SORT_NONE - allerdings erst ab der nächsten Version (5.4).

              Ahh. Danke. :-)

            2. Also, im englischen Original sieht man, dass der Parameter $sorting_order erweitert wurde. Der kennt jetzt auch einen konstanten Wert namens SCANDIR_SORT_NONE - allerdings erst ab der nächsten Version (5.4).

              Wenn man die Konstante in einer PHP-Version < 5.4 angibt, kommt es natürlich zu einem Fehler. Allerdings lautet dieser:

              Warning: scandir() expects parameter 2 to be long, string given in ...

              Laut Handbuch muss der zweite Parameter aber ein Integer sein. Wie kommt's?

              1. Tach!

                Wenn man die Konstante in einer PHP-Version < 5.4 angibt, kommt es natürlich zu einem Fehler. Allerdings lautet dieser:
                Warning: scandir() expects parameter 2 to be long, string given in ...
                Laut Handbuch muss der zweite Parameter aber ein Integer sein. Wie kommt's?

                PHPs automatische Korrektur schlägt da zu. Eine Zeichenkette, die kein Funktionsname oder ein reserviertes Wort ist, wird erst als Konstante zu interpretieren versucht. Existiert keine mit solchem Namen nimmt PHP an, man habe einen String notieren wollen.

                dedlfix.

                1. PHPs automatische Korrektur schlägt da zu. Eine Zeichenkette, die kein Funktionsname oder ein reserviertes Wort ist, wird erst als Konstante zu interpretieren versucht. Existiert keine mit solchem Namen nimmt PHP an, man habe einen String notieren wollen.

                  Das ist so weit klar. Aber warum wird laut Fehlermeldung als zweiter Parameter der Datentyp Long erwartet, obwohl es sich laut Handbuch um einen Integer handeln muss?

                  1. Tach!

                    Aber warum wird laut Fehlermeldung als zweiter Parameter der Datentyp Long erwartet, obwohl es sich laut Handbuch um einen Integer handeln muss?

                    Das ist anscheinend eine ungenaue Formulierung. Der Datentyp long ist unter PHP nicht vorhanden. Wahrscheinlich will das C-Pendant zu dieser Funktion ein long haben.

                    dedlfix.

                    1. Das ist anscheinend eine ungenaue Formulierung. Der Datentyp long ist unter PHP nicht vorhanden. Wahrscheinlich will das C-Pendant zu dieser Funktion ein long haben.

                      Ach so. Vielen Dank!

      2. Hallo,

        Lohnt es sich hier eigentlich aus Performance-Gründen opendir() mit readdir() statt scan() zu verwenden? Denn die implizite Sortierung von scan() wird hier ja nicht gebraucht.

        Du kannst sie aber ausnutzen :-)

        Ausgehend von Deinem Beispiel:

        Array
        (
            [0] => musik.mp3
            [1] => bild.jpg
            [2] => mehr_musik.mp3
            [3] => noch_ein_bild.jpg
            [4] => text.txt
            [5] => textdokument.doc
        )

        hast Du nun festgestellt, dass die Reihenfolge durch scandir() wie folgt aussieht:

        Array
        (
            [0] => bild.jpg
            [1] => mehr_musik.mp3
            [2] => musik.mp3
            [3] => noch_ein_bild.jpg
            [4] => textdokument.doc
            [5] => text.txt
        )

        Bei einer Handvoll von Einträgen ist Performance eh' völlig gleichgültig, aber bei vielen Einträgen kann ein anderes Verfahren schneller sein.

        Hier das alternative Verfahren als Pseudocode.
        Dabei werden die Dateinamen als assoziatives Array abgelegt. Als Schlüssel werden die Dateiendungen verwendet und die Werte sind wiederum ein Array, das die Dateinamen mit der entsprechenden Endung enthält.

        das heißt bei Deinem Beispiel sieht das Resultat wie folgt aus:

        Array (
            'jpg' => Array (
                        'bild.jpg',
                        'noch_ein_bild.jpg'
                     ),
            'mp3' => Array (
                        'mehr_musik.mp3',
                        'musik.mp3'
                     ),
            'doc' => Array (
                        'textdokument.doc'
                     ),
            'txt' => Array (
                        'text.txt'
                     )
        )

        Nun muss man dieses Array nur noch nach den Schlüsseln sortieren, z.B. mit ksort und anschließend die einzelnen Arrays mit sort sortieren. Wenn wir jedoch ausnutzen, dass scandir() eine sortierte Liste erzeugt, so sind die inneren Arrays durch das linearen Abarbeiten der sortierten Liste automatisch ebenfalls sortiert :-)

        Algorithmus:

        Lege ein leeres Resultatarray an
        Für jeden Dateinamen in der alphabetisch sortierten Dateinamenliste
            Bestimme die Dateiendung des Dateinamens
            Wenn die Dateiendung noch nicht als Schlüssel im Resultatarray existiert
                Lege einen Eintrag der Form (Dateiendung => leeres Array) an
            Ende Wenn
            Hänge den Dateinamen an das passende Array an.
        Ende Für
        Sortiere das Resultatarray aufsteigend nach den Schlüsseln

        Die Ausgabe dieser Datenstruktur ist einfacher, weil der Gruppenwechsel automatisch eingebaut ist:

        Für jedes Element im Resultatarray
            Schreibe eine Überschrift mit dem Schlüssel
            Schreibe den Listenanfang
            Für jeden Dateinamen im Wertearray
                Schreibe ein Listenelement
            Ende Für
            Schreibe das Listenende
        Ende Für

        Wäre die Ausgangsliste nicht vorsortiert, so müsstest Du nur zwischen Aufbau des Arrays von Arrays die Einzelarrays sortieren:

        Für jedes Element im Resultatarray
            Sortiere das Wertearray
        Ende Für

        Implementiere alle Verfahren und ermittle die Laufzeit bei unterschiedlichen Ausgangsdaten :-)

        Freundliche Grüße

        Vinzenz

        1. Du kannst sie aber ausnutzen :-)
          .
          .
          .

          Uff. :O

          1. Hallo Nick,

            Du kannst sie aber ausnutzen :-)
            .
            .
            .

            Uff. :O

            Verfahren nicht verstanden :-(

            So schwer sollte das gar nicht sein. Du kannst jeden meiner Schritte eins-zu-eins in PHP-Code umsetzen. Ich mach' das mal für den Aufbau der von mir vorgeschlagenen Datenstruktur:

            <?php  
              [link:http://de3.php.net/manual/en/function.header.php@title=header]("Content-Type: text/plain");  # ich spare mir den [link:http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel@title=Kontextwechsel]  
              # Liste, wie sie scandir() geliefert hat:  
              $liste = array(  
                'bild.jpg',  
                'mehr_musik.mp3',  
                'musik.mp3',  
                'noch_ein_bild.jpg',  
                'textdokument.doc',  
                'text.txt'  
              );  
              
              # Aufbau unserer Datenstruktur  
              # Lege ein leeres Resultatarray an  
              $resultat = array();  
              
              # Für jeden Dateinamen in der Liste der Dateinamen  
              foreach ($liste as $filename) {  
                # Bestimme die Dateiendung des Dateinamens  
                $extension = [link:http://de3.php.net/manual/en/function.pathinfo.php@title=pathinfo]($filename, PATHINFO_EXTENSION);  
              
                # Wenn die Dateiendung noch nicht als Schlüssel im Resultat existiert  
                if (![link:http://de3.php.net/manual/en/function.array-key-exists.php@title=array_key_exists]($extension, $resultat)) {  
                  # Dann lege einen Eintrag der Form (Dateiendung => leeres Array) an  
                  $resultat[$extension] = array();  
                }  
              
                # Hänge den Dateinamen an das passende [link:http://de3.php.net/manual/en/language.types.array.php@title=Array] an  
                $resultat[$extension][] = $filename;  
              }  
              
              # Schauen wir's uns an:  
              [link:http://de3.php.net/manual/en/function.var-dump.php@title=var_dump]($resultat);  
            ?>  
            
            

            Ausgabe:

            array(4) {
              ["jpg"]=>
              array(2) {
                [0]=>
                string(8) "bild.jpg"
                [1]=>
                string(17) "noch_ein_bild.jpg"
              }
              ["mp3"]=>
              array(2) {
                [0]=>
                string(14) "mehr_musik.mp3"
                [1]=>
                string(9) "musik.mp3"
              }
              ["doc"]=>
              array(1) {
                [0]=>
                string(16) "textdokument.doc"
              }
              ["txt"]=>
              array(1) {
                [0]=>
                string(8) "text.txt"
              }
            }

            Also das strukturierte Array - wie von mir beschrieben.

            Die Umwandlung kannst Du in eine Funktion packen:

            /*  
              array get_filenames_by_extension ( array $input )  
              strukturiert ein Array von Dateinamen in ein assoziatives Array von Arrays,  
              wobei die Dateiendungen der Dateinamen als Schlüssel verwendet werden und  
              die Werte nummerierte Arrays der Dateinamen mit dem gleichen Dateityp sind  
              
              Verwendeter Algorithmus:  
              
              Lege ein leeres Resultatarray an  
              Für jeden Dateinamen in der alphabetisch sortierten Dateinamenliste  
                Bestimme die Dateiendung des Dateinamens  
                Wenn die Dateiendung noch nicht als Schlüssel im Resultatarray existiert  
                  Lege einen Eintrag der Form (Dateiendung => leeres Array) an  
                Ende Wenn  
                Hänge den Dateinamen an das passende Array an.  
              Ende Für  
            */  
            function get_filenames_by_extension ($input) {  
              $resultat = array();  
              
              foreach ($input as $filename) {  
                $extension = pathinfo($filename, PATHINFO_EXTENSION);  
                if (!array_key_exists($extension, $resultat)) {  
                  $resultat[$extension] = array();  
                }  
                $resultat[$extension][] = $filename;  
              }  
              return $resultat;  
            }
            

            Nun kannst Du die Ausgabe ebenfalls als Funktion schreiben, die ein solch aufgebautes Array übergeben bekommt und die Ausgabe genauso vornimmt, wie Du das haben willst.

            Freundliche Grüße

            Vinzenz

            1. Ganz herzlichen Dank für deine ausführliche Erklärung. Super! :-)

              (Allerdings würde mich schon auch noch interessieren, wie die Ausgabe mit dem "Gruppenwechsel" zu realisieren ist. Dazu habe ich leider nicht viel gefunden.)

              1. Hallo,

                Ganz herzlichen Dank für deine ausführliche Erklärung. Super! :-)

                (Allerdings würde mich schon auch noch interessieren, wie die Ausgabe mit dem "Gruppenwechsel" zu realisieren ist. Dazu habe ich leider nicht viel gefunden.)

                Das Prinzip hat doch dedlfix beschrieben, sein Satz hilft meiner Meinung nach mehr als der Wikipedia-Artikel, den Tom verlinkt hat.

                dedlfix:
                    "Man merkt sich immer den vorhergehenden Gruppierwert (in deinem
                     Fall die Endung) und wenn der wechselt, beendest du die bisherige
                     und beginnst eine neue Gruppe."

                Was Du aus dem Wikipedia-Artikel mitnehmen kannst, ist, dass der erste Datensatz getrennt betrachtet werden sollte und nach Durchlaufen der Schleife(n) etwas Nacharbeit fällig werden kann:

                Wie kannst Du somit Deine neu sortierte Liste ausgeben?
                Deine Liste liegt wie folgt vor:

                  
                  $liste = array(  
                    'textdokument.doc',  
                    'bild.jpg',  
                    'noch_ein_bild.jpg',  
                    'mehr_musik.mp3',  
                    'musik.mp3',  
                    'text.txt'  
                  );  
                
                

                Algorithmus:

                Lies den ersten Dateinamen aus (und entferne ihn aus dem Array)
                Ermittle die Gruppe dieses Dateinamens (die Erweiterung ) und merke diese
                Schreibe die Überschrift der ersten Gruppe
                Beginne die Liste der Dateinamen der ersten Gruppe
                Schreibe das erste Listenelement
                Für jeden Dateinamen im Restarray
                    Ermittle die Gruppe des aktuellen Dateinamens
                    Wenn dieser sich von der gemerkten Gruppe unterscheidet
                        Merke die neue Gruppe
                        Beende die noch offene Liste
                        Schreibe die Überschrift der neuen Gruppe
                        Beginne die Liste der neuen Gruppe
                    Ende Wenn
                    Schreibe das Listenelement mit dem aktuellen Dateinamen
                Ende Für
                Aufräumarbeiten: Beende die letzte Liste

                Im Gegensatz zum Wikipediaartikel sparen wir uns durch unser Wenn-Dann-Konstrukt die innere Schleife über die Elemente der Gruppe :-)

                Verstehst Du den Algorithmus?
                Kannst Du ihn umsetzen?

                Wenn Du eine der Fragen mit Nein beantwortest, sag' bitte, woran Du hängen geblieben bist.

                Freundliche Grüße

                Vinzenz

                1. Hallo Vinzenz,

                  nochmals herzlichen Dank für deine Hilfe.

                  Lies den ersten Dateinamen aus (und entferne ihn aus dem Array)

                  Eine Frage noch: Wieso soll ich den ersten Dateinamen aus dem Array entfernen?

                  Beste Grüße
                  Nick

                  1. Hallo,

                    Lies den ersten Dateinamen aus (und entferne ihn aus dem Array)

                    Eine Frage noch: Wieso soll ich den ersten Dateinamen aus dem Array entfernen?

                    damit Du für die Schleife einfach foreach verwenden kannst. Das Array brauchst Du sowieso nicht mehr :-) Schließlich übergibst Du Deine Liste einer Funktion, die somit eine Kopie des Arrays erhält. Und dann macht man sich das Leben so einfach wie möglich ...

                    Freundliche Grüße

                    Vinzenz

                    1. Hallo Vinzenz!

                      damit Du für die Schleife einfach foreach verwenden kannst. Das Array brauchst Du sowieso nicht mehr :-) Schließlich übergibst Du Deine Liste einer Funktion, die somit eine Kopie des Arrays erhält. Und dann macht man sich das Leben so einfach wie möglich ...

                      Ach so, jetzt verstehe ich. Nochmals vielen Dank für deine Hilfe und ein schönes Wochenende!

                      Beste Grüße
                      Nick

  2. Tach!

    Gegeben ist ein Array, das eine Reihe von Dateinamen verschiedenen Typs beinhaltet:
    Nun sollen nach Dateityp sortierte Listen ausgegeben werden, die in sich wiederum alphabetisch sortiert sind:

    Nimm eine Sortierfunktion mit benutzerdefinierter Vergleichsfunktion: usort(). Für das Ausgeben kannst du eine Technik namens Gruppenwechsel nehmen. Man merkt sich immer den vorhergehenden Gruppierwert (in deinem Fall die Endung) und wenn der wechselt, beendest du die bisherige und beginnst eine neue Gruppe.

    dedlfix.

    1. Hallo dedlfix!

      Danke für deine Antwort.

      Nimm eine Sortierfunktion mit benutzerdefinierter Vergleichsfunktion: usort(). Für das Ausgeben kannst du eine Technik namens Gruppenwechsel nehmen. Man merkt sich immer den vorhergehenden Gruppierwert (in deinem Fall die Endung) und wenn der wechselt, beendest du die bisherige und beginnst eine neue Gruppe.

      Unter was finde ich den Gruppenwechsel im PHP-Handbuch?

      Beste Grüße
      Nick

      1. Hello,

        Unter was finde ich den Gruppenwechsel im PHP-Handbuch?

        Keine Ahnung, ob sich Handbuch auch mit den Grundlagen der Programmierung beschäftigt, aber per Suchmaschine und in einschlägigen Informationssammlungen findet man das ganz leicht:

        http://lmgtfy.com/?q=Gruppenwechsel
        http://de.wikipedia.org/wiki/Gruppenwechsel

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Keine Ahnung, ob sich Handbuch auch mit den Grundlagen der Programmierung beschäftigt, aber per Suchmaschine und in einschlägigen Informationssammlungen findet man das ganz leicht:

          http://lmgtfy.com/?q=Gruppenwechsel
          http://de.wikipedia.org/wiki/Gruppenwechsel

          Also zwei ineinander verschachtelte Schleifen?

    2. Nimm eine Sortierfunktion mit benutzerdefinierter Vergleichsfunktion: usort().

      Wenn man damit nach der Dateiendung sortiert, sind die Dateinamen ja innerhalb der jeweiligen Endung nicht mehr alphabetisch sortiert. Hast du dafür noch einen Tipp?

      1. Tach!

        Nimm eine Sortierfunktion mit benutzerdefinierter Vergleichsfunktion: usort().
        Wenn man damit nach der Dateiendung sortiert, sind die Dateinamen ja innerhalb der jeweiligen Endung nicht mehr alphabetisch sortiert. Hast du dafür noch einen Tipp?

        Wie würdest du das machen, wenn du die Dateinamen auf Zetteln stehen hast? Wer kommt vorher, wer nachher? Wenn die Endungen unterschiedlich sind, ist das in einem Schritt entschieden. Wenn die Endungen gleich sind, ...

        dedlfix.

        1. Wie würdest du das machen, wenn du die Dateinamen auf Zetteln stehen hast? Wer kommt vorher, wer nachher? Wenn die Endungen unterschiedlich sind, ist das in einem Schritt entschieden. Wenn die Endungen gleich sind, ...

          ... muss man verschachteln? Innerhalb der Bedingung "if ($a_endung == $b_endung)" der cmp-Funktion muss noch etwas passieren. Das habe ich versucht, aber nicht hinbekommen.

          <?php  
          function cmp($a, $b) {  
              $a_array = explode('.', $a);  
              $a_endung = $a_array[sizeof($a_array) - 1];  
            
              $b_array = explode('.', $b);  
              $b_endung = $b_array[sizeof($b_array) - 1];  
            
              if ($a_endung == $b_endung) {  
                  return 0;  
              }  
              return ($a_endung < $b_endung) ? -1 : 1;  
          }  
            
          $dateiliste = array('musik.mp3', 'bild.jpg', 'mehr_musik.mp3', 'noch_ein_bild.jpg', 'text.txt', 'textdokument.doc');  
            
          usort($dateiliste, "cmp");  
          ?>
          
          1. Hallo,

            Wie würdest du das machen, wenn du die Dateinamen auf Zetteln stehen hast? Wer kommt vorher, wer nachher? Wenn die Endungen unterschiedlich sind, ist das in einem Schritt entschieden. Wenn die Endungen gleich sind, ...

            ... muss man verschachteln? Innerhalb der Bedingung "if ($a_endung == $b_endung)" der cmp-Funktion muss noch etwas passieren.

            Das habe ich versucht, aber nicht hinbekommen.

            davon ist aber in Deinem Code nichts zu sehen.

              
            
            > function cmp($a, $b) {  
              
            /*  
            
            >     $a_array = explode('.', $a);  
            >     $a_endung = $a_array[sizeof($a_array) - 1];  
            >   
            >     $b_array = explode('.', $b);  
            >     $b_endung = $b_array[sizeof($b_array) - 1];  
            
            */  
              
            # Was ist, wenn eine Datei keine Endung aufweist?  
              
            # Nutze stattdessen lieber [link:http://de3.php.net/manual/de/function.pathinfo.php@title=pathinfo()] mit geeigneten Optionen :-)  
              
              
            
            >     if ($a_endung == $b_endung) {  
            
                      # Wenn die Endungen gleich sind, ...  
                      # Was entscheidet dann über die Sortierung?  
              
                      # Das ist zuwenig, dann sind alle Dateien mit gleicher Endung gleich groß  
            
            >         return 0;  
            >     }  
            >     return ($a_endung < $b_endung) ? -1 : 1;  
            > }  
            
            

            Freundliche Grüße

            Vinzenz

            1. davon ist aber in Deinem Code nichts zu sehen.

              Meinen Versuch habe ich lieber mal weggelassen. ;-)

              Was ist, wenn eine Datei keine Endung aufweist?

              Nutze stattdessen lieber pathinfo() mit geeigneten Optionen :-)

              Danke für den Tipp. (Eine Option sollte reichen. ;-))

              # Wenn die Endungen gleich sind, ...
                        # Was entscheidet dann über die Sortierung?

              Der Dateiname.

              # Das ist zuwenig, dann sind alle Dateien mit gleicher Endung gleich groß

              Also an der Stelle noch sort() aufrufen?

              1. Hallo,

                # Wenn die Endungen gleich sind, ...
                          # Was entscheidet dann über die Sortierung?

                Der Dateiname.

                # Das ist zuwenig, dann sind alle Dateien mit gleicher Endung gleich groß
                Also an der Stelle noch sort() aufrufen?

                Nein, sondern die Dateinamen vergleichen :-)

                Freundliche Grüße

                Vinzenz

                1. Nein, sondern die Dateinamen vergleichen :-)

                  Ich habe es endlich hinbekommen. Vielen Dank!

      2. Hello,

        Wenn man damit nach der Dateiendung sortiert, sind die Dateinamen ja innerhalb der jeweiligen Endung nicht mehr alphabetisch sortiert. Hast du dafür noch einen Tipp?

        Das höchstwertigste Sortierglied muss vorne stehen, also links, wenn man, wie üblich, die Wertigkeit von links nach rechts auswertet.

        usort() benötigst Du also nicht, wenn Du dem erhaltenen Array ein zusätzliches Element hinzufügst.

        dateiname          sortierbegriff

        picture.mpg        mpg.picture
           text.txt           txt.text

        oder Du machst es "vernünftig" und atomarisierst die Anteile. Dann benötigst Du aber später wieder Funktionen, wie usort(), u, die erhaltene Struktur zu sortieren.

        Das würde aber auf jeden Fall bedeuten, dass Du gleich beim Scannen des Directorys beide Elemente erzeugst.

        while <dateiname gefunden>

        dateiname ins Array einfügen
              dateiname aufspalten
              Extensionanteil + Namensanteil ins Array einfügen

        endwhile

        Array über die Elemente <Extensionanteil + Namensanteil> sortieren

        Array-Elemente <dateiname> nach der Sortierung in <Extensionanteil + Namensanteil> ausgeben.

        Und ja, sowas geht am besten mit einem "Spaltenarray", also einer Struktur, in der die einzelnen Spalten über ihren Index korrespondieren.

        Such mal im Forum danach. Da gibt es schon genügend "Anregung" dazu :-)

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Vielen Dank, auch ein interessanter Ansatz.