Kackfohgel: Maximalwert von mehrdimensionalen assoziativen Array

Hallo,

ich will ein Maximalwert aus einem mehrdimensionales assoziatives Array ausgeben:

Beispiel (das Original ist leider um ein vielfaches größer):

  
Array (  
[Axel] => Array ([name] => Axel [alter] => 31 [geschlecht] => m [bild] => 123.gif )  
[Katja] => Array ( [name] => Katja [alter] => 28 [geschlecht] => w [bild] => 456.gif )  
[Chris] => Array ( [name] => Chris [alter] => 82 [geschlecht] => m [bild] => 789.gif )  
[Jani] => Array ( [name] => Jani [alter] => 27 [geschlecht] => w [bild] => 012.png ) [Ali] => Array ( [name] => Ali [alter] => 27 [geschlecht] => m [bild] => 345.gif )  
[Jenni] => Array ( [name] => Jenni [alter] => 25 [geschlecht] => w [bild] => 678.gif )  
)

Hier will ich jetzt das Bild zu des/der Ältesten ausgeben. Im Beispiel ist Chris am ältesten und deshalb soll mir "789.gif" angezeigt werden.

Meine Versuch mit max()
echo max($testfeld['Axel']['alter'], $testfeld['Katja']['alter'], $testfeld['Chris']['alter'], $testfeld['Jani']['alter'], $testfeld['Ali']['alter'], $testfeld['Jenni']['alter'])
bringt mich nicht wirklich weiter, da ich zum einem ja am Ende nicht den Maximalwert vom Alter ausgeben will, sondern das Bild zu der ältesten Person. Außerdem ist es problematisch, dass das Array assoziativ und nicht nummmerisch ist, weil ich so (bei dem v. g. Lösungsansatz) jeden Key wissen und angeben muss (und das Original hat einige hundert Datensätze).

Eine Sortierung der Liste ist nicht ausdrücklich gewünscht, darf aber bei möglichen Lösungsvorschlägen gerne in Betracht gezogen werden.

Also nochmal als Frage formuliert:
Wie kann ich mir aus dem v. g. Array das Bild des/der Ältesten ausgeben lassen?

Freundliche Grüße
Kackfohgel

  1. Hallo,

    ich würde jetzt einfach mal die Datensätze in einer Schleife durchlaufen und mir dabei den jeweils den Datensatz mit dem größten Wert und den bisher größten Wert selbst merken. Du brauchst ja schließlich nur den größten Wert.

    Pseudocode:

      
    max_index = null  
    max_value = 0  
      
    foreach list as index => item  
     if item >= max_value  
       max_value = item  
       max_index = index  
     endif  
    endforeach  
      
    list[max_index]  
    
    

    Viele Grüße Novi

    --
    "(...) deshalb mag ich Binärtechnik. Da gibt es nur drei Zustände: High, Low und Kaputt." (Wau Holland)
  2. Hi!

    ich will ein Maximalwert aus einem mehrdimensionales assoziatives Array ausgeben:
    Wie kann ich mir aus dem v. g. Array das Bild des/der Ältesten ausgeben lassen?

    Du hast sicher nichts dagegen, wenn du den gesamten Datensatz bekommst. Dann kannst du das Array auf eben diesen einen Datensatz reduzieren - mit array_reduce(). Das Beispiel im Handbuch summiert und multipliziert, aber du kannst auch den Maximalwert ermitteln lassen. Die Funktion will neben dem Array auch eine Callback-Funktion haben. Diese bekommt zwei Parameter übergeben - je ein Datensatz. Du vergleichst von beiden Parametern/Datensätzen das Feld alter und gibst den Datensatz mit dem höchsten Alter zurück - den gesamten Datensatz, nicht nur das Altersfeld. Mit dem Trinitätsoperator ?: ist das sogar nur ein Einzeiler und kann auch als anonyme Funktion geschrieben werden, wenn du mindestens PHP 5.3 verwendest.

    Bleibt noch ein Problem: der Erstaufruf bekommt nur einen Datensatz aus dem Array und als zweiten Parameter ein null. Du kannst nun zusätzlich noch auf dieses null prüfen und dann ungesehen den anderen Wert zurückgeben. Dann hast du aber bei jedem Callback-Aufruf die Prüfung ob der eine Parameter null ist und das gleiche nochmal mit dem zweiten Parameter. Einfacher ist es, array_reduce() mit dem dritten Parameter aufzurufen. Übergibt da ein array(alter => 0), dann funktioniert deine Altersprüfung problemlos.

    Eine Sortierung der Liste ist nicht ausdrücklich gewünscht, darf aber bei möglichen Lösungsvorschlägen gerne in Betracht gezogen werden.

    Auch das ginge, mit usort() und derselben Callback-Funktion wie bei array_reduce(). Der gesuchte Datensatz ist dann entweder das erste oder das letzte Element im Array, je nachden, in welcher Richtung du sortierst. Das ist aber aufwendiger, weil nicht wie bei array_reduce() nur einmal iteriert werden muss, sondern auch die unerwünschten Datensätze in die richtige Reihenfolge gebracht werden müssen.

    Lo!

    1. Hallo ChrisB, Dedlfix und Novi.

      Vielen lieben Dank für eure sehr hilfreichen Antworten. Insbesondere das sehr ausführliche Posting von dir dedlfix hat mir sehr weiter geholfen.

      Für die mit ähnlichen Problemen und für das Archiv, hier mein Code, der mir zu dem im Startposting genannten Array, das Bild des/der Ältesten ausgibt:

        
      function max_alter ($a, $b)  
      {  
      return $a['alter'] > $b['alter'] ? $a : $b;  
      }  
        
      $testfeld = array_reduce($testfeld, "max_alter", 0);  
      echo $testfeld['bild'];  
      
      

      Wünsche allen einen schönen Abend.

      Freundliche Grüße
      Kackfohgel

      1. Hi!

        function max_alter ($a, $b) {

        return $a['alter'] > $b['alter'] ? $a : $b;
        }

        $testfeld = array_reduce($testfeld, "max_alter", 0);
        echo $testfeld['bild'];

          
        Du hast den Code vermutlich nur zum Testen verwendet. Ansonsten würde man doch eher das Resultat des Reduzierens in einer neuen Variable speichern und sich nicht das Original-Array überschreiben.  
          
          
        Aber mal was anders: Jetzt bin ich doch etwas verwundert, denn der Code löst bei vollem error\_reporting keine Fehlermeldung aus. Eine Notice hätte ich ja wenigstens erwartet. Beim ersten Aufruf bekommt max\_alter() die 0 vom dritten Parameter von array\_reduce()-Aufruf übergeben. Es findet also quasi ein Lesezugriff auf 0['alter'] statt. Doch PHP lässt das einfach so durchgehen, wobei das Ergebnis vom Ausdruck null ist. Das gleiche passiert (oder passiert nicht, wenn man eine Meldung erwartet), wenn man die 0 weglässt oder null übergibt. Auch null['irgendwas'] bringt keinen Fehler. Also, wenn man es direkt notiert schon, dann ist es ein Syntaxfehler, aber 0 oder null als Variableninhalt und dann einen Array-Zugriff darauf ergibt nur ein stillschweigendes null.  
          
          
        Lo!
        
        1. Guten Morgen!

          Du hast den Code vermutlich nur zum Testen verwendet. Ansonsten würde man doch eher das Resultat des Reduzierens in einer neuen Variable speichern und sich nicht das Original-Array überschreiben.

          Danke für den Hinweis. Gerade weil ich mir den Code als Beispielcode sichern will, bin ich froh über alle Verbesserungsvorschläge.

          Das hier ist ja nur ein bewusst einfach gehaltenes Beispiel, das Original ist um einiges größer. Es handelt sich dabei um Daten aus einer Schnittstelle. In dem gelieferten Array sind erstmal auch redundante Daten dabei und ich speichere die relevanten Informationen derzeit in einem weiteren Array (später sollen die in eine MySQL-Tabelle gespeichert werden). Insofern wird das Ursprungs-Array aus der Schnittstelle im Original ohnehin nicht verändert.

          Gruß
          Kackfohgel

  3. Hi,

    ich will ein Maximalwert aus einem mehrdimensionales assoziatives Array ausgeben: […]

    Eine Sortierung der Liste ist nicht ausdrücklich gewünscht

    Das wäre zumindest die „simple“ Variante, die auch ein Anfänger problemlos hinkriegen sollte.

    Also nochmal als Frage formuliert:
    Wie kann ich mir aus dem v. g. Array das Bild des/der Ältesten ausgeben lassen?

    array_reduce lässt sich dazu auch verwenden – in dem man eine Callback-Funktion verwendet, die zwei Array-Elemente vergleicht und das größere zurückgibt. (Damit bekommst du das „größte“-Array-Element zurück, und musst dann das Bild nur noch aus diesem entnehmen.)

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?