1. Finden des kleinsten Werts mit min()
An die praktische Funktion min() kann entweder ein Array von Werten (zum Beispiel min(array(1, 2, 3))) oder eine Menge von Werten als Parameter (zum Beispiel min(1, 2, 3)) übergeben werden. Die Funktion sucht dann aus allen übergebenen Werten den kleinsten heraus und gibt diesen zurück. Das nachfolgende Beispiel demonstriert die Anwendung mit einem Array:
<?php $arr = array(17, 19, 4, 42, 99); $min = min($arr); var_dump($min); ?>
int(4)
2. foreach-Schleife
Will man die Suche nach dem Minimum selbst implementieren, dann ist der wohl einfachste Weg die Anwendung einer foreach-Schleife. Diese iteriert über jeden Wert im Array und vergleicht ihn mit dem bisher gefundenen Minimum. Falls der Wert kleiner ist, wird er als das neue Minimum übernommen. Eine weitere kleine Prüfung ist notwendig, um zu erkennen, ob es sich gerade um den ersten Wert handelt. In diesem Fall muss der Wert immer übernommen werden, da mit noch keinem vorherigem Wert verglichen werden kann.
<?php $arr = array(17, 19, 4, 42, 99); $min = null; foreach ($arr as $val) { // wenn $min noch nicht definiert wurde, wird der Wert immer uebernommen (ist beim ersten Element der Fall) // alternativ wird mit dem bisher niedrigsten Wert verglichen und der kleinere genommen // (Das ließe sich auch als ein verschachtelter bedingter Ausdruck schreiben, waere aber nur schwer lesbar.) if ($min===null) { $min = $val; } else { $min = ($val<$min ? $val : $min); } } var_dump($min); ?>
int(4)
Alternativ wäre im vorherigen Beispiel auch möglich:
- $min auf PHP_INT_MAX (maximaler Integerwert) zu setzen. Dann könnte $min in der Schleife über schlicht ($val<$min ? $val : $min) definiert werden. Die zusätzliche Prüfung ob es sich um die erste Iteration handelt, würde wegfallen. Das Problem dabei: Das Array könnte Float-Werte enthalten, welche oberhalb von PHP_INT_MAX liegen. Diese würden nicht erfasst werden. Die Lösung wäre daher nicht korrekt.
- Statt $min===null könnte man auch die aktuelle Iterationsnummer erfassen und prüfen, ob diese 0 ist. Das würde allerdings eine weitere Variable erfordern. Alternativ wäre es möglich, den aktuellen Array-Schlüssel über „foreach ($arr as $key=>$val)” in $key zu erfassen und diesen auszuwerten. Die Schlüssel im Array müssen aber nicht zwangsweise bei 0 beginnen, sodass auch diese Lösung manchmal fehlschlagen würde.
- $min könnte am Anfang auf den Wert des ersten Elements im Array gesetzt werden. Das lässt sich allerdings nicht so als Einzeiler formulieren, dass es auch mit leeren Arrays funktioniert, sowie mit solchen, deren Schlüssel nicht bei 0 beginnen.
3. array_walk()
Die foreach-Schleife lässt sich ohne große Probleme durch die Funktion array_walk($array, $callback) ersetzen, welche über $array iteriert und auf jedes Element $callback anwendet. Die Zuweisung zu $min erfolgt letztlich weiterhin genauso.
<?php $arr = array(17, 18, 4, 42, 99); $min = null; array_walk($arr, function($val) use (&$min) { if ($min===null) { $min = $val; } else { $min = ($val<$min ? $val : $min); } }); var_dump($min); ?>
int(4)
4. array_reduce()
array_reduce($array, $callback, $start) wendet auf jedes Paar von Werten in $array die Funktion $callback an und ersetzt das Paar durch die Rückgabe der Funktion. Bei der ersten „Iteration” ist $start einer der beiden Werte. Hier wird über current($arr) der erste Wert im Array als Startwert vorgegeben. Das funktioniert aber nur dann, wenn der Array-Zeiger auf den ersten Wert (oder zumindest auf irgendeinen Wert im Array) gerichtet ist, sonst muss zuvor reset($arr) durchgeführt werden. Dies hat die bereits beschriebenen Probleme (Fehler falls Array leer ist, oder falls die Schlüssel nicht von 0 bis n durchnummeriert sind). Alternativ könnte auch eine Callback-Funktion ähnlich der bereits verwendeten übergeben werden. $start könnte dann auf NULL gesetzt werden.
<?php $arr = array(17, 18, 4, 42, 99); $min = array_reduce($arr, function($left, $right) { return ($left<$right ? $left : $right); }, current($arr)); var_dump($min); ?>
int(4)
5. Mit Schlüssel und Prüfung der Werte
In diesem Beispiel wird die weiter oben dargestellte foreach-Schleife ausgebaut. Nun soll sie nicht einfach den kleinsten Wert, sondern dessen Schlüssel zurückgeben. Das bietet etwas mehr Flexibilität (zum Beispiel könnte so der kleinste Wert im Array gesucht und gelöscht werden). Zudem prüft sie nun jeden Wert über is_int() darauf, ob es sich bei diesem überhaupt um einen Integer handelt.
<?php $arr = array(17, 18, 4, 42, 99); $minKey = null; foreach ($arr as $key=>$val) { if (is_int($val)) { if ($minKey===null || $val<$arr[$minKey]) { $minKey = $key; } } } echo("Der niedrigste Wert ist {$arr[$minKey]} mit dem Schlüssel $minKey."); ?>
Der niedrigste Wert ist 4 mit dem Schlüssel 2.
Die vorherige, angepasste foreach-Schleife kann leicht auch in eine spezielle Funktion ausgelagert werden. Diese wird hier als getKeyOfMin() bezeichnet, erwartet ein Array und gibt den Schlüssel des niedrigsten Werts zurück (oder NULL falls keiner gefunden wurde).
<?php function getKeyOfMin(array $arr) { $minKey = null; foreach ($arr as $key=>$val) { if (is_int($val)) { if ($minKey===null || $val<$arr[$minKey]) { $minKey = $key; } } } return $minKey; } $arr = array(17, 18, 4, 42, 99); $minKey = getKeyOfMin($arr); echo("Der niedrigste Wert ist {$arr[$minKey]} mit dem Schlüssel $minKey."); ?>
Der niedrigste Wert ist 4 mit dem Schlüssel 2.