Design für Print und Web

Mehrdimensionalen Array nach Feldern sortieren

05.02.2007 um 11:20 Uhr
Emersacker
abgelegt unter PHP

Emersacker. Ein in vielen PHP-Foren angefragtes Problem ist das Sortieren eines mehrdimensionalen Arrays, z.B aus einer Datenbankabfrage, nach dem Feldinhalt eines bestimmten Feldes, z.B. dem Namen, oder der Preishöhe, etc..

Meist handelt es sich um einen verschachelten assoziativen Array, der sortiert werden muss.
PHP stellt dazu zwar mehrere eigene Funktion zur Verfügung, doch unter Benutzung eines Hilfsarrays, den man aus den Inhalten des Feldes, nachdem sortiert werden soll, erstellt, ist die Lösung des Problems ganz einfach:

Um ganz flexibel auf unterschiedliche Suchanforderungen (nach verschiedenen Feldern sortieren zu können) reagieren zu können, wird der Feldname hier in einer Variablen abgelegt.

Weiterführende Links:

Code Listing:

  • Listing 1: sort_test.php
    <?php

    // Ein mehrdimensionaler Array zum Testen,
    // z.B. das Ergebnis einer Datenbankabfrage
    // mit mysql_fetch_array():

    $daten = array (
        array(
            
    'Vorname'=>'Susanne',
            
    'Nachname'=>'Meier',
            
    'Alter'=>9
        
    ),
        array(
            
    'Vorname'=>'Markus',
            
    'Nachname'=>'Schmidt',
            
    'Alter'=>35
        
    ),
        array(
            
    'Vorname'=>'Gabi',
            
    'Nachname'=>'Weber',
            
    'Alter'=>29
        
    ),
        array(
            
    'Vorname'=>'Tobias',
            
    'Nachname'=>'Bauer',
            
    'Alter'=>71
        
    ),
    );

    // Ausgabe des Testarrays, vor dem Sortieren:
    PRINT 'Vorher:<br><pre>';
    PRINT_R ($daten);
    PRINT 
    '</pre>';

    // Aufgabe: absteigende Sortierung der Datenstze
    // nach dem Nachnamen

    // LSUNG MIT HILFS-ARRAY:

    // Den Namen des gewnschten Sortierfelds in einer Variablen speichern:
    $feldname 'Nachname';

    // Mittels einer foreach-Schleife
    // Aus allen Datenstzen den Wert im Feld 'Nachname'
    // in den neuen Array "$Nachname" schreiben,
    foreach($daten as $id => $datensatz) {

        
    // Namen des Arrays dynamisch aus bergebenem Feldnamen erzeugen,
        // den Originalschlssel als Index beibehalten,
        // den Wert von Nachname als neues Element dem Array anhngen:
        
        
    ${$feldname}[$id] = $datensatz[$feldname];
    }

    // Den neuen Array - unter Beibehhaltung der Schlsssel(!)- sortieren:
    asort(${$feldname});

    // SORTIERERGEBNIS - AUSGABE:

    // mit einer foreach-Schleife den Hilfs-Array durchlaufen,
    // nur die gespeicherten Schlssel auslesen, und mit ihnen
    // die einzelnen Elemente des Original-Arrays
    // in der gewnschten Reihenfolge ausgeben:
    PRINT "Sortiert aufsteigend nach $feldname:<br><pre>";
    foreach (${
    $feldname} as $k => $v) {
        ECHO 
    "[$k] => ";
        
    PRINT_R ($daten[$k]);
    }
    PRINT 
    '</pre>';


    // WEITERRFHRUNG:
    // Die Sortierordnung lsst sich nun leicht abwandeln,
    // indem man der Variablen $feldname anfangs einen anderen Wert bergibt,
    // z.B. "Alter".
    $feldname 'Alter';
    // Dann alles wie gehabt:
    foreach($daten as $id => $datensatz) {
        ${
    $feldname}[$id] = $datensatz[$feldname];
    }
    asort(${$feldname});

    // Will man eine absteigende Sortierung,
    // ist diese Anweisung, unmittelbar vor der Ausgabe eingefgt,
    // hilfreich:
    ${$feldname} = array_reverse(${$feldname},true);

    PRINT 
    "Sortiert absteigend nach $feldname:<br><pre>";
    foreach (${
    $feldname} as $k => $v) {
        ECHO 
    "[$k] => ";
        
    PRINT_R ($daten[$k]);
    }
    PRINT 
    '</pre>';

    // Natrlich kann man seine Daten auch in einer Tabelle ausgeben:
    ECHO "
    <table padding='5' border='3'>
    <caption>Sortiert absteigend nach 
    $feldname:</caption>
    <tr>
    <th>ID#</th>
    <th>Nachname</th>
    <th>Vorname</th>
    <th>Alter</th>
    </tr>
    "
    ;
    foreach (${
    $feldname} as $i => $v) {
        ECHO 
    "<tr>\n";
        ECHO 
    "<td>$i</td>\n";
        ECHO 
    "<td>".$daten[$i]["Nachname"].", </td>\n";
        ECHO 
    "<td>".$daten[$i]["Vorname"]."</td>\n";
        ECHO 
    "<td>".$daten[$i]["Alter"]."</td>\n";
        ECHO 
    "<tr>\n";
    }
    ECHO 
    '</table>';


    // Oder mit Funktion uasort(), die Schlssel bleiben erhalten:

    function compare($a$b) {
        global 
    $feldname
        return 
    strnatcasecmp($a[$feldname],$b[$feldname]);
    }

    $feldname 'Vorname';
    uasort($daten'compare');
    ECHO 
    "
    <table padding='5' border='3'>
    <caption>Sortiert aufsteigend nach 
    $feldname:</caption>
    <tr>
    <th>ID#</th>
    <th>Nachname</th>
    <th>Vorname</th>
    <th>Alter</th>
    </tr>
    "
    ;
    foreach (
    $daten as $i => $v) {

        ECHO 
    "<tr>\n";
        ECHO 
    "<td>$i</td>\n";
        ECHO 
    "<td>".$daten[$i]["Nachname"].", </td>\n";
        ECHO 
    "<td>".$daten[$i]["Vorname"]."</td>\n";
        ECHO 
    "<td>".$daten[$i]["Alter"]."</td>\n";
        ECHO 
    "<tr>\n";
    }

    ECHO 
    '</table>';


    highlight_file(__FILE__);
    ?>

    sort_test.php (3,4 KB): Beispiel aufrufen