Array nach Index sortieren mit PHP
Wenn man es dem Benutzer einer Klasse möglich machen will, Elemente zu einem Array hinzuzufügen und die Position des einzelnen Elements angeben möchte, kann man das machen, indem man der Methode, die die Elemente hinzufügt, nicht nur das eigentliche Element mitgibt, sondern auch die Position. In der Methode selbst schreibt man dann die Position in die Eckige Klammer des Arrays. So wie ich es hier gemacht habe:
class Liste { private $elements = array(); public function addElement($content, $position) { $this->elements[$position] = (string)$content; } public function display() { foreach($this->elements as $element) { echo $element."\n"; } } } $liste = new Liste; $liste->addElement("zehn", 10); $liste->addElement("eins", 1); $liste->addElement("neun", 9); $liste->addElement("vier", 4); $liste->display();
Will man das ganze jetzt per foreach-Schleife (Das macht hier die display-Methode) ausgeben, wird man feststellen, dass PHP bei foreach nicht nach den Keys (Indexe / Schlüssel) sortiert, sondern alles in der Reihenfolge abarbeitet, in der es hinzugefügt wurde.
Wers nicht glaubt, schaut hier, was ausgegeben wird:
zehn eins neun vier
Aber hierfür hat PHP eine Lösung parat. Die uksort-Funktion! Sie erwartet 2 Parameter. Der erste Parameter ist der Index des ersten zu vergleichenden Arrayelements, der zweite ist der Index des zweiten Elements.
Wenn man möchte, dass das erste Element vor das zweite kommt, gibt man -1 zurück. Wenn man möchte, dass es hinter das zweite kommt, gibt man 1 zurück. Wenn beide Elemente den gleichen Key haben (was nie zutrifft), gibt man 0 zurück.
So sieht die Umsetzung in PHP aus: (Hier wird alles objektorientiert gemacht. Es geht aber auch prozedural, dazu später mehr)
class Liste { private $elements = array(); public function addElement($content, $position) { $this->elements[$position] = (string)$content; } public function sort() { uksort($this->elements, array($this, "sortAlg")); } static public function sortAlg($a, $b) { if($a == $b){ return 0; } return ($a < $b) ? -1 : 1; } public function display() { foreach($this->elements as $element) { echo $element."\n"; } } } $liste = new Liste; $liste->addElement("zehn", 10); $liste->addElement("eins", 1); $liste->addElement("neun", 9); $liste->addElement("vier", 4); $liste->sort(); $liste->display();
Wenn man $liste->sort() ausführt, wird von der sort-Methode folgender Befehl ausgeführt:
uksort($this->elements, array($this, "sortAlg"));
Das erste Argument ist das Array, das sortiert werden soll. Das zweite ist ein Array, das das Objekt mit dem Sortieralgorithmus und den Namen der STATISCHEN Methode beinhaltet.
Die Ausgabe von diesem Skript wird so sein:
eins vier neun zehn
Alles schön geordnet!
Es geht auch prozedural
Man kann uksort aber auch verwenden, ohne dafür eine statische Methode in einer Klasse zu schreiben. Dazu schreibt man einfach eine ganz normale Funktion, wie z.B. hier:
function compare($a, $b) { if($a == $b) { return 0; } if($a < $b) { return -1; } if($a > $b) { return 1; } }
Danach definieren wir ein Array, das ungeordnete Elemente enthält:
$array = array(4 => "vier", 1 => "eins", 3 => "drei", 0 => "null", 8 => "acht");
Um die Elemente zu sortieren, verwendet man uksort so:
uksort($array, "compare");
Jetzt sind alle Array-Einträge von $array nach den Keys sortiert. Zum Test kann man sich das so anzeigen lassen:
foreach($array as $el) { echo $el." "; } echo "\n"; uksort($array, "comp"); foreach($array as $el) { echo $el." "; }
Ausgabe des Testskripts:
vier eins drei null acht
null eins drei vier acht
EDIT: Wie ich gerade sehe, gibt es für genau diese Aufgabe schon eine fertige Funktion von PHP: Die ksort-Funktion! Verwendet wird sie so:
$fruits = array("d" => "Zitrone", "a" => "Orange", "b" => "Banane", "c" => "Apfel"); ksort($fruits); foreach ($fruits as $key => $val) { echo "$key = $val\n"; }
Ausgabe:
a = Orange
b = Banane
c = Apfel
d = Zitrone
Das funktioniert auch mit numerischen Indexen.
An sich ganz nett.
Würd noch die Interfaces aus der SPL
implementieren. Da gibts einige die ganz
nette Methoden um Arrays zu bearbeiten
Damit habe ich mich bisher noch nicht beschäftigt, wenn ich ehrlich bin.
Aber danke für den Tipp! Man lernt nie aus